为什么Class.getSuperClass()方法不能得到完全超类型的实例?

时间:2013-04-07 13:20:54

标签: java class rtti

假设有两个类,即PetDogPet类是Dog类的超类。

Ques01:

当我编码如下时,发生编译错误:Type mismatch: cannot convert from Class<capture#2-of ? super Dog> to Class<Pet>

Class<Pet> c1 = Dog.class.getSuperclass();

必须是这样的:

Class<? super Dog> c2 = Dog.class.getSuperclass();

此外,当我使用c2.newInstance()时,它只返回Object个实例。为什么我不能得到Class Instance class Pet

Ques02:

当我System.out c2.getName()时,它会输出"pet"!所以c2只是得到了我想要的信息。

我真的很困惑。任何人都可以提供帮助吗?非常感谢!

2 个答案:

答案 0 :(得分:2)

Java中的reflexion API比泛型更老。 RTTI中的一些方法反映了这一点。

此外,RTTI是运行时功能,而泛型是编译功能。有时,编译器没有足够的信息来检查运行时类型是否正确。

但是,例如,您的newInstance示例无效。

public class Test {
    class Pet {}

    class Dog extends Pet {}

    public static void main(String[] args) throws Exception {
        Class<Dog> dogClass = Dog.class;
        Dog dog = dogClass.newInstance();
    }
}

编译没有问题,因为在Class<T>上方法声明为T newInstance()

如果我们采用getSuperClass()示例,您必须先了解编译器不知道getSuperClass()的作用。它只查看方法声明。这就是为什么它不知道返回的类实际上是Pet。它只是将变量的类型与getSuperClass返回的对象的类型进行比较。变量是Class<Pet>,返回的对象是Class<? super Dog>,这是不一样的。编译器不模拟getSuperClass实现,也不知道返回的确切对象。

答案 1 :(得分:0)

一篇文章中有太多问题......

这里的一般答案是遗留和向后兼容性。泛型已经在1.5版本中引入了java。从版本1.0开始,方法getSuperClass()存在于java中。 java创建者无法破坏与旧版本的兼容性,因此他们没有更改其原型。这就是为什么你必须将Dog.class.getSuperclass();转换为Class<? super Dog>或类似的东西。

同样关于newInstance(),遗憾的是,它会在创建“正确”实例时返回普通对象。所以你也必须在这种情况下施展。因此getName()返回正确的类名:类确实是Pet