0

试图理解为什么 Java 在使用 Class 参数传递类型信息时在推断类型和检查类型边界方面表现不同。

以这段代码为例:

public class TypeTest<T extends Number> {
    Class<T> type;

    TypeTest(Class<T> type) { this.type = type; }

    static <S extends Number> void sMethod(Class<S> type) {}

    <S extends Number>  void method(Class<S> type) {}


    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        // 1.
        TypeTest<Integer> obj = new TypeTest(Object.class);  // compiles, unchecked call and assignment warnings

        // 2.
        obj.method(Object.class); // compile-time error, S not within bound 

        TypeTest obj1 = new TypeTest(Object.class);  // compiles, unchecked call and assignment warnings

        // 3.
        obj1.method(Object.class); // compiles, unchecked call warning .             

        // 4.
        TypeTest.sMethod(Object.class); // compile time error, Object not within bounds

        // 5.
        new TypeTest<Object>(Object.class); // compile time error, Object not within bounds
    }

}

使用静态方法(4.),我们不能传入任何不是数字的东西,这似乎是提供的边界最自然的行为。

但是,对于构造函数(1.、5.),我们必须明确指定类型参数才能获得与 4 相同的行为。否则,似乎 T 类型参数值不会从 Object.class 变量中自动推断出来。

构造函数和静态方法的这种差异来自哪里?

另一个我不完全理解的情况是 2. 和 3 之间的区别。为什么相同的操作编译或不编译仅取决于 TypeTest 对象的构造方式,而类类型参数 T 与方法没有任何关系类型参数 S?

4

3 回答 3

1

只能推断为方法或构造函数声明的泛型类型。所以

<S> void method() {}
 ^ this can be inferred

<S> TypeTest() {}
 ^ this can be inferred

构造泛型类时无法推断泛型类的泛型类型:

class TypeTest<T> {}
               ^ this must be specified explicitly when using "new TypeTest"
                 or in Java 7 you can explicitly specify the diamond operator

正如其他人所提到的,当您不使用new TypeTest()任何尖括号时,您使用的是原始类型。原始类型的工作方式必须与泛型之前的工作方式相同,以保持与旧代码的兼容性。所以表达式new TypeTest()将具有类型TypeTest(原始类型),而不是TypeTest<something>.

于 2012-10-18T18:36:02.930 回答
1

new TypeTest(Object.class)是原始类型的表达式TypeTest,这就是它的设计方式。所以当然,没有类型推断是因为没有类型可以推断

于 2012-10-18T17:25:50.730 回答
1

当您省略泛型类型的类型参数时——也就是说,任何时候你键入时都TypeTest没有<Something>——Java 会忽略对所有该类型的所有泛型检查。

有关详细信息,请参阅http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

于 2012-10-18T17:25:53.147 回答