为什么我在下面的代码中没有收到编译错误?我得到一个
ClassCastException
,这有点令人困惑。是因为他们有血缘关系吗?
class Ink {}
Interface Printable {}
class ColorInk extends Ink implements Printable {}
class BlackInk extends Ink {}
class TwistInTaleCasting {
public static void main(String args[]) {
Printable printable = null;
BlackInk blackInk = new BlackInk();
printable = (Printable)blackInk;
}
}
为什么我在下面的代码中没有得到编译错误?
因为编译器只关心您尝试转换的表达式的静态类型。
看这两行:
BlackInk blackInk = new BlackInk();
printable = (Printable)blackInk;
您知道,在第二行中,由于第一行,值
blackInk
仅引用类型为BlackInk
的对象,但编译器不这样做。据编译器所知(编译第二行时),它可能实际上是:
BlackInk blackInk = new PrintableBlackInk();
printable = (Printable)blackInk;
...其中
PrintableBlackInk
是一个扩展 BlackInk
并实现 Printable
的类。因此,从 BlackInk
类型的表达式转换为 Printable
是有效的(在编译时)。如果您将 BlackInk
设为 final
类,那么编译器就知道它无法工作(除非该值为空)并且会在编译时失败,如下所示:
error: inconvertible types
printable = (Printable)blackInk;
^
required: Printable
found: BlackInk
详细信息请参见JLS 5.5.1必须
等到执行时才能看到失败,因为转换在编译时有效。
TwistInTaleCasting
和
Printable
没有关系,因此会抛出类转换异常。由于 ClassCastException 是**未检查异常**,因此可以在代码中不处理任何此类情况。被指定为超类或接口时不需要强制转换。您可以显式地转换回实际的子类型。 (这里可能会发生 ClassCastException。)
请参阅下面我的示例。
class Parent {}
class Child extends Parent {}
Parent parent = new Child(); // Actual Child type assigned as Parent.
Child child = (Child) parent; // Explicitly casting back to actual type.
// ClassCastException at runtime when casting incompatible types:
// Parent (bigger) into Child (more specific).
Parent parent = new Parent();
Child child = (Child) parent;
// Compile error if casting to unrelated type (that makes no sense to compiler).
String s = (String) parent;