为什么将对象转换到不相关的接口会产生ClassCastException而不是编译时异常?

huangapple go评论77阅读模式
英文:

Why casting to unrelated interface produce ClassCastException instead of compile time exception?

问题

为什么在这个代码片段中,尽管Tree接口与Bug类无关,但它不会产生编译时异常?

interface Tree {}
class Bug {
    public static void main(String[] args) {
        Bug bug = new Bug();
        Tree tree = (Tree) bug;
    }
}
英文:

Why in this snippet while Tree interface is not related to Bug class it does not produce compile time exception?

interface Tree {}
class Bug {
    public static void main(String[] args) {
        Bug bug = new Bug();
        Tree tree = (Tree) bug;
    }
}

答案1

得分: 2

Bug 标记为 final,你将会得到预期的编译错误。

这是因为 Bug 可能有一个子类实际上实现了 Tree 接口。如果 Bug 实际上存储了对该子类实例的引用,那么类型转换将会成功。由于存在类型转换可能成功的情况,编译器不会阻止你进行类型转换。

在大多数情况下,你可以从任何非 final 类型转换到任何接口。根据 JLS §5.5.1,当你尝试将引用类型为 S 的变量转换为接口 T 时:

如果 S 不是 final 类型(§8.1.1),那么如果存在接口 T 的超类型 X,和变量 S 的超类型 Y,使得 XY 都是可以证明不同的参数化类型,并且 XY 的擦除操作是相同的,那么在编译时会产生错误。

否则,在编译时转换总是合法的(因为即使 S 没有实现 TS 的子类可能会实现)。

英文:

Mark Bug as final and you will get your compiler error as expected.

This is because Bug could have a subclass that does implement Tree. If bug actually stores a reference to an instance of that subclass, then the cast will succeed. Since there is a chance that the cast can succeed, the compiler doesn't stop you from casting.

In most cases, you can cast from any non-final class to any interface. According to the JLS §5.5.1, when you try to cast a variable of reference type S to interface T:

> If S is not a final class (§8.1.1), then, if there exists a supertype X of T, and a supertype Y of S, such that both X and Y are provably distinct parameterized types, and that the erasures of X and Y are the same, a compile-time error occurs.
>
> Otherwise, the cast is always legal at compile time (because even if S does not implement T, a subclass of S might).

huangapple
  • 本文由 发表于 2020年10月18日 15:47:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/64410934.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定