【问题标题】:Why is casting not working here as I expect? [duplicate]为什么铸造不能像我预期的那样在这里工作? [复制]
【发布时间】:2015-11-01 13:34:44
【问题描述】:

这是我的示例代码:

public class Bar extends Foo {
}

@SuppressWarnings("unchecked")
public class Foo {

    public static void main(String[] args) {
        Foo foo = new Bar();
        Class<Foo> x = (Class<Foo>) foo.getClass();
        System.out.println(x);
    }
}

我希望这个程序的输出是:Foo.class,因为我正在转换为 Class 但是我在输出中看到:

class Bar

为什么?

如果我从代码中删除铸造部分,程序甚至不会编译:

java: incompatible types
required: java.lang.Class<Foo>
found:    java.lang.Class<capture#1 of ? extends Foo>

为什么编译器强制我强制转换?

【问题讨论】:

  • @RealSkeptic 这些问题有何相同之处?
  • 好吧,即使XY, 之间存在某种联系,A&lt;X&gt; 也不是 A&lt;Y&gt;,这就是为什么你不能从 Class&lt;? extends X&gt; 分配给 @987654329 @。这就是那个问题的要点,也是你问题的要点。

标签: java class casting


【解决方案1】:

为什么?

因为对象的类是Bar,而不是Foo(您使用new Bar() 创建了对象),并且您已经明确询问对象它是什么类。你有一个对象的Foo reference,但这并不会改变对象的实际情况。

如果我从代码中删除铸造部分,程序甚至不会编译:

这与Foo/Bar 无关。您已为 x 指定了特定类型 (Class&lt;Foo&gt;),但 Object#getClass 的类型为 Class&lt;?&gt;


来自您的评论:

是的,我询问了对象本身,但随后我将其转换为Class&lt;Foo&gt; 并将数据存储在“x”中。这让我很困惑..

转换对对象完全没有影响,转换纯粹是为了改变你对对象的引用类型。它是同一个对象,没有改变,你所做的只是改变你对它的引用的类型。这可能会改变您可以访问对象的哪些方面,并且如果您尝试强制转换为对象不是的东西,则可能(当然)失败。

【讨论】:

  • 是的,我询问了对象本身,但随后我将其封装为 Class 并将数据存储在“x”中。这让我很困惑..
  • 投射不会改变对象的类型。将鼠标(称为动物)投射到大象身上,不会将鼠标变成大象。它会失败,因为老鼠不是大象。仅当动物确实是大象时,将动物投给大象才有效。您的转换不会失败,因为泛型已被删除:在运行时,Java 无法区分 Class 和 Class。但是你的编译器警告你这是一个不安全的转换:它不能检查这个类确实是一个 Class。如果可以的话,演员表就会失败。
猜你喜欢
  • 1970-01-01
  • 2014-10-14
  • 2015-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-07
相关资源
最近更新 更多