代码之家  ›  专栏  ›  技术社区  ›  Judking

为什么Class.getSuperClass()方法不能精确地获取超类类型实例?

  •  2
  • Judking  · 技术社区  · 11 年前

    假设有两个类,即 Pet Dog . 宠物 class是的超类

    问题01:

    当我按照以下方式进行编码时,出现了一个编译错误: 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 ?

    问题02:

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

    我真的被这些弄糊涂了。有人能帮忙吗?谢谢!

    2 回复  |  直到 11 年前
        1
  •  2
  •   Sulthan    11 年前

    Java中的反射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() 例如,您必须首先理解编译器不知道什么 获取超级类() 做它只查看方法声明。这就是为什么它不知道返回的类实际上是 Pet 。它只是将变量的类型与返回的对象的类型进行比较 getSuperClass 。变量为 Class<Pet> 并且返回的对象是 Class<? super Dog> ,这不一样。编译器不模拟 获取超级类 实现,并且不知道返回的确切对象。

        2
  •  0
  •   AlexR    11 年前

    一篇帖子里有太多问题。。。。

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

    这也是关于 newInstance() 不幸的是,它在创建“正确”的实例时返回了普通对象。所以在这种情况下,你也必须投。因此 getName() 返回正确的类名:该类确实是 Pet .