将已知类型的引用转换为类型层次结构之外的接口

Opt*_*ime 3 java oop casting

假设你有一个像这样的干净课:

public class A {
    // Stuff
}
Run Code Online (Sandbox Code Playgroud)

和这样的界面:

public interface G {
    // Stuff
}
Run Code Online (Sandbox Code Playgroud)

为什么我被允许这样做:

A a = new A();
((G) a) // No errors thrown
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么当它们彼此无关时,应该可以从A类转换到接口G. 有人可以向我解释一下吗?


跟进.如果我做以下事情:

public class C implements G {
    // Stuff
}
Run Code Online (Sandbox Code Playgroud)

这不会编译:

((C) a)
Run Code Online (Sandbox Code Playgroud)

实现接口的类和接口之间有什么区别?

编辑:我得到一个编译器错误说:

无法从A转换为C.

Nat*_*hes 7

转换意味着你比编译器更了解什么是有效的.您告诉编译器关闭并跟随您的线索.在少数情况下,编译器可以告诉某个强制转换是无效的,但它很容易被愚弄.

大多数强制转换都倾向于从Object到其他东西,例如从非泛化集合中获取对象或使用PortableRemoteObject.narrow获取远程对象时.这些强制转换始终是编译的,因为无论你投射到什么(只要它是一个Object,而不是一个原语)总是一个有效的Object子类.

参考类型转换(5.5.1)一节中,Java语言规范中有一些转换规则.如果编译器可以发现类之间没有关系(编译器可以告诉类是不同的,并且两者都不是另一个的子类)那么它将拒绝转换.

添加的示例很有趣,它失败了,因为编译器有足够的信息来告诉强制转换.如果您将代码更改为:

    A a = new A();
    G g = (G)a;
    Object o = a;
    C c = (C)o;
Run Code Online (Sandbox Code Playgroud)

然后它再次编译好(即使它同样错误).

  • +1.引用我的一个朋友:`ClassCastException意味着编译器比你更了解,欺骗了你,你就堕落了. (3认同)