Java 类转换规则

标签 java class inheritance casting polymorphism

    public static void main(String[] args) {
       new Redwood().go();
    }
    void go() {
       go2(new Tree(), new Redwood());
       go2((Redwood) new Tree(), new Redwood());
    }
    void go2(Tree t1, Redwood r1) {
       Redwood r2 = (Redwood)t1;
       Tree t2 = (Tree)r1;
    }
}

给定类 Redwood extends Tree,main() 方法在 Redwood 中,Tree 是一个只有默认构造函数的空类;这个考试问题的答案是“当代码试图将 Tree 向下转型为 Redwood 时,将抛出 ClassCastException。”

我想知道异常抛出的原因和位置。据我了解,您可以声明 Tree t1 = new Redwood() 那么为什么我不能将 Tree 直接转换为 Redwood?

最佳答案

通过使用强制转换,你实际上是在告诉编译器“相信我。我是专业人士,我知道我在做什么,我知道虽然你不能保证,但我告诉你这tree 变量肯定是红木。”

由于树实际上不是红木(它是一棵树,您可以执行 Tree tree = new Redwood(); 它会是红木)VM 在运行时抛出异常,因为您违反了该信任(你告诉编译器一切都会好的,但事实并非如此!)

编译器比盲目接受一切要聪明一些,如果你尝试在不同的继承层次结构中转换对象(例如将红木转换为字符串),那么编译器会把它扔回给你,因为它知道永远不会可能工作。

因为您本质上只是阻止编译器提示,所以每次您强制转换时,重要的是检查您不会通过在 if 语句(或类似的东西)中使用 instanceof 来导致 ClassCastException。

引用http://www.xyzws.com/Javafaq/why-down-casting-throws-classcastexception/125

关于Java 类转换规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50010099/

相关文章:

Java:如何捕获在 Method.invoke 中创建的异常?

java - 检查两个列表中的元素

javascript - 滚动到时更改 <li> 的类

php - 为什么 PHP 不自动调用父构造函数?

C# 遍历子类

java - 为 toString 更改 HashMap 的键值分隔符

java - Activity A 调用 B,B 调用 C,需要 C 将数据发送回 A

javascript - TypeScript 静态类

objective-c - 是类结构还是结构指针

Python - 初始化父类