有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么上课。getClass()可以与类不同。cast()返回类型?

我希望你能在这件事上帮助我

我一直在寻找这个问题的答案,但我能找到的只是泛型类型用法或关于反射的一般说明

假设我们有一个父类和一个扩展该父类的子类。因此,请参见下文:

Parent v = new Child();

如果我使v.getClass()返回Child。然而,如果我使v.getClass().cast()它将从类型Parent返回一个对象

有人知道为什么会这样吗?我还查看了Java API文档,但找不到原因

谢谢你的想法


共 (2) 个答案

  1. # 1 楼答案

    这是因为getClass()方法和泛型的设计

    出于兼容性的原因,getClass()方法没有使其成为泛型,因此它返回类型为的实例

    Class<?> 
    

    不是

    Class<Child> 
    

    正如你所料

    Class<?> 
    

    表示类型参数为Object的泛型类型

    那么,返回类型

    Class<?>.cast() 
    

    方法就是对象。也就是说,这种方法的通用性不起作用

    你可以写

    v3 = ( (Class<Child>) v.getClass() ).cast(v2);
    

    但这是毫无意义的,因为你只会写作

    v3 = ( Child ) v.getClass().cast(v2);
    

    此外,您应该记住,泛型只在编译时工作。也就是说,泛型仅用于在IDE上进行类型检查。在运行时,所有泛型都是

    <?>
    

    所以,实际上,cast()方法在运行时什么都不做。只有当您有类型的实例时,才可以使用此存根

    Class<something>
    
  2. # 2 楼答案

    对象的运行时类型与变量或表达式的编译时类型之间有一个重要的区别。表达式的编译时类型只能通过其组件的编译时类型来确定。作为这些表达式的值的对象的运行时类型可以根据表达式参数的运行时类型来确定,只要它们与编译时类型兼容

    为了说明这一点,在您的特定代码示例中:

    • 变量v具有编译时类型Parent,但分配给它的值的运行时类型Child
    • 表达式v.getClass()将具有编译时类型Class<? extends Parent>(表示Parent类型或其子类之一的类对象)。它在运行时的值将是Child.class,类型为Class<Child>
    • 表达式v.getClass().cast(obj)将具有编译时类型Parent。它的运行时类型将是obj的运行时类型,因为它的运行时值实际上是obj。(也就是说,如果obj是一种可分配给Child类型变量的类型,否则cast()将抛出ClassCastException