为什么ClassCastException但不是编译错误?

时间:2014-08-15 12:37:33

标签: java inheritance classcastexception

为什么我在下面的代码中没有出现编译错误?我得到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;
   }
}

3 个答案:

答案 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)

设置将正确编译。但是在运行时,由于TwistInTaleCastingPrintable没有关系,因此抛出了类强制转换异常。由于ClassCastException是**未经检查的异常**,因此您可以在代码中处理任何此类情况。