Java泛型:为什么someObject.getClass()不返回Class <! - ?延伸T - >?

时间:2010-12-16 12:07:40

标签: java class generics types type-safety

我希望从编译时间以及运行时方面来看,.getClass()提供正确类型的返回值不会有问题。

但我一定是错的。

public class _GetClassGenerics2 {

  static class MyClass {
  }

  public static void main(String[] args) {
    MyClass myInstance = new MyClass();
    // here it works
    Class<? extends MyClass> type = myInstance.getClass();

    myMethod(myInstance);
  }

  public static <T extends MyClass> void myMethod(T instance) {
    Class<? extends T> type = instance.getClass();
// java.lang.RuntimeException: Uncompilable source code - incompatible types
//  required: java.lang.Class<? extends T>
//  found:    java.lang.Class<capture#1 of ? extends _GetClassGenerics2.MyClass>
  }

}

编辑:它不适用于Class<T>Class<? super T>

4 个答案:

答案 0 :(得分:6)

java.lang.Class不代表类型(使用java.lang.reflect.Type)。如果T代表ArrayList<String>,那么Class<ArrayList<String>>就没有任何意义。

值得注意的是,在这种特殊情况下,该方法不需要通用。

public static <T extends MyClass> void myMethod(T instance) {

相当于:

public static void myMethod(MyClass instance) {

答案 1 :(得分:3)

根据the Javadoc of the getClass method

  

实际结果类型为Class<? extends |X|>,其中| X |是擦除   表达式的静态类型   在哪个getClass被调用。对于   例如,此处不需要强制转换   代码片段

此处,代码段中|X|的值为MyClass,因此instance.getClass()只能分配给Class<? extends MyClass>Class<?>

这个特定措辞的原因是因为当你说这个变量的类型为T <T extends MyClass>时,可以有多个类扩展MyClass,因此能够满足T extends MyClass标准。没有运行时信息,就无法知道方法中传递了MyClass的哪个具体实现子类。因此,为了提供通用解决方案,它返回<? extends MyClass>,因为无论传递什么类实例,它都适用于MyClass的任何子类。

答案 2 :(得分:0)

Java不支持泛型类型&lt; this&gt; e.g。

对象可以实现

class Object {
    Class<this> getClass()
}

但getClass()无法表达它将返回一个类型,该类型是该对象的类。编译器对本方法的作用没有本地的理解。

恕我直言,应该支持此行为。

答案 3 :(得分:0)

而不是

Class<? extends T> type = instance.getClass();

你需要使用

Class<? extends MyClass> type = instance.getClass();

您无法在此处直接使用T

原因是Object.getClass()(您正在调用)的方法签名。它是:

public final Class<? extends Object> getClass()

因此,您尝试将Class<? extends Object>转换为Class<? extends T>,这是不允许的(因为您正在向下转换)。 允许使用显式强制转换:

Class<? extends T> type = (Class<? extends T>) instance.getClass();

将起作用(尽管它会生成类型安全警告)。