Java 推断泛型类型

Java inferred generic types

我正在寻找一个类似的推断捕获的泛型类型的概念,类似于以下方法片段,但是取而代之的是捕获泛型类型的class:

public <X, Y, Z> static void someMethod(ObjectInterface<X, Y, Z> object) {
    // code that uses inferred generic type parameters X, Y and Z...
}

此代码段中的代码将捕获类型并将它们分配给通用参数类型 XYZ。这允许在代码主体内使用泛型类型变量,并使该方法在使用中更加灵活。在此代码段中,如果调用方法时未指定类型(即未参数化),则 Java 将推断类型,即 someMethod(instaceOfImplementedObject) 将起作用并推断类型。

我的问题是,我有以下(简化的)对象接口结构和实现该接口的对象:

public interface ObjectInterface<X, Y, Z> {
    //...
}

class ImplementedObject implements ObjectInterface<SomeType1, SomeType2, SomeType3> {
    //...
}

然后我有其他 classes 必须捕获相当多的通用类型变量,其中之一是实现 ObjectInterface<X, Y, Z> 的对象。在这样的 class 中,我还需要处理在捕获的对象中定义的类型(XYZ)。

以下(不理想,而且非常简化)代码有效:

public class ClassWorks<X, Y, Z, N extends ObjectInterface<X, Y, Z>> {
    // code body uses X, Y, Z and N...
}

然而,这对于试图use/initiate这个class的人来说非常麻烦,即使是在这个简化版本中,例如:

public class ImplementedObject implements ObjectInterface<Integer, Double, String> {
    //...
}

public class RandomExample {
    public static void main(String[] args) {
        ObjectInterface<Integer, Double, String> implementedObj = new ImplementedObject();
        ClassWorks<Integer, Double, String, ImplementedObject>> example = new ClassWorks<Integer, Double, String, ImplementedObject>(/* possible params */);
    }
}

有没有办法 "extract" 或捕获这些类型,以便推断它们而不是像工作示例中的 ClassWorks 那样显式? 可能类似于以下内容(注意这不起作用):

pulic class WishfullClass<N extends ObjectInterface<X, Y, Z>> {
    // type N is captured; X, Y and Z is not explicitly captured.
    // code uses type N, as well as X, Y and Z
    // where, X, Y and Z is inferred somehow from N.
}

编辑: 因此,WishfullClass 的一个实施示例为:

public class ImplementedObject implements ObjectInterface<Integer, Double, String> {
    //...
}

public class WishfullExample {
    public static void main(String[] args) {
        ObjectInterface<Integer, Double, String> implementedObj = new ImplementedObject();
        WishFullClass<ImplementedObject> example = new WishfullClass<ImplementedObject>(/* possible params */);
    }
}

即。编译器应该从 class 的声明中知道 ImplementedObject 它将 ObjectInterface<Integer, Double, String> 实现为 X、Y 和 Z。

请注意,以上这些非常简化,在实际代码中并不是唯一需要捕获的参数,所以这三个额外的参数有很大的不同;实现的对象也捕获通用类型,

所以理想情况下,我只想共同捕获扩展 ObjectInterface<X, Y, Z> 并推断出 XYZ 的对象。有没有办法做到这一点?

即someMethod 的片段显示了如何为方法的范围推断 X、Y 和 Z。我的问题是,有没有一种方法可以通过仅捕获扩展 ObjectInterface.

的类型来推断 class 的整个范围的 X、Y 和 Z

这个问题我遇到了一些麻烦wording/explaining,所以如果有什么不明白的地方,请问清楚:)

于是经过一番研究,我在课本上找到了答案Effective Java, by Joshua Block; Item 27: Favor generic methods。我一直在寻找的是 simplify/reduce 在调用通用构造函数时重复类型参数 - 即使其不那么麻烦并且不重复已经给出的参数。

确实不可能推断构造函数的类型,但是有一种方法可以利用泛型方法来减少构造函数的重复和类型参数 - 通过为每个构造函数创建泛型工厂方法并推断其中的类型参数相反。

这是解释整个情况的资料,以下是从教科书上引用的:

One noteworthy feature of generic methods is that you needn’t specify the value of the type parameter explicitly as you must when invoking generic constructors. The compiler figures out the value of the type parameters by examining the types of the method arguments. In the case of the program above, the compiler sees that both arguments to union are of type Set , so it knows that the type parameter E must be String. This process is called type inference.

As discussed in Item 1, you can exploit the type inference provided by generic method invocation to ease the process of creating parameterized type instances. To refresh your memory, the need to pass the values of type parameters explicitly when invoking generic constructors can be annoying. The type parameters appear redundantly on the left- and right-hand sides of variable declarations:

// Parameterized type instance creation with constructor`
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

To eliminate this redundancy, write a generic static factory method corresponding to each constructor that you want to use. For example, here is a generic static factory method corresponding to the parameterless HashMap constructor:

// Generic static factory method
public static <K,V> HashMap<K,V> newHashMap() {
    return new HashMap<K,V>();
}

With this generic static factory method, you can replace the repetitious declaration above with this concise one:

// Parameterized type instance creation with static factory
Map<String, List<String>> anagrams = newHashMap();

It would be nice if the language did the same kind of type inference when invoking constructors on generic types as it does when invoking generic methods. Someday it might, but as of release 1.6, it does not.

Map<String, List<String>> anagrams = new HashMap<>();

在 Java 7 之后也会这样做。 <> 是钻石算子。