为什么我在下面的代码中没有出现编译错误?我得到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;
}
}
答案 0 :(得分:10)
为什么我在下面的代码中没有出现编译错误?
因为编译器只关心你试图转换的表达式的静态类型。
看看这两行:
BlackInk blackInk = new BlackInk();
printable = (Printable)blackInk;
您知道在第二行中,由于第一行,值blackInk
仅引用类型BlackInk
的对象,但编译器没有'吨。对于所有编译器都知道(编译第二行时)可能实际上是:
BlackInk blackInk = new PrintableBlackInk();
printable = (Printable)blackInk;
...其中PrintableBlackInk
是一个扩展BlackInk
并实施Printable
的类。因此,从BlackInk
类型的表达式转换为Printable
是有效的(在编译时)。如果你使BlackInk
成为final
类,那么编译器知道它没有方式它将起作用(除非值为null)并且将在编译时,像这样:
error: inconvertible types
printable = (Printable)blackInk;
^
required: Printable
found: BlackInk
详情请见JLS 5.5.1。
否则,我们有等到执行时间才能看到失败,因为强制转换在编译时是有效的。
答案 1 :(得分:3)
ClassCastException是运行时异常,这就是为什么要编译代码但在运行时获取ClassCastException的原因。您也可以检查javadocs - ClassCastException扩展RuntimeException: http://docs.oracle.com/javase/7/docs/api/java/lang/ClassCastException.html
您获得ClassCastException的原因显然是因为您正在尝试将BlackInk的实例强制转换为Printable(当您将对象强制转换为不是实例的子类时,您将在运行时获得ClassCastException)。简而言之,在进行转换时,您需要使用类型转换,并且它必须是有效的操作,否则您将在运行时获得ClassCastExecption。
答案 2 :(得分:1)
设置将正确编译。但是在运行时,由于TwistInTaleCasting
和Printable
没有关系,因此抛出了类强制转换异常。由于ClassCastException是**未经检查的异常**,因此您可以在代码中处理任何此类情况。