为什么出现 ClassCastException 而不是编译错误?

问题描述 投票:0回答:4

为什么我在下面的代码中没有收到编译错误?我得到一个

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;
   }
}
java inheritance classcastexception
4个回答
12
投票

为什么我在下面的代码中没有得到编译错误?

因为编译器只关心您尝试转换的表达式的静态类型。

看这两行:

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

否则,我们

必须

等到执行时才能看到失败,因为转换在编译时有效。


3
投票
http://docs.oracle.com/javase/7/docs/api/java/lang/ClassCastException.html

你得到ClassCastException的原因显然是因为你试图将BlackInk的实例转换为Printable(当你将一个对象转换为它不是实例的子类时,你将在运行时得到ClassCastException)。简而言之,当您进行转换时,您正在使用类型转换,并且它需要是有效的操作,否则您将在运行时得到 ClassCastExecption。


1
投票
TwistInTaleCasting

Printable
没有关系,因此会抛出类转换异常。由于 ClassCastException 是**未检查异常**,因此可以在代码中不处理任何此类情况。
    


0
投票

被指定为超类或接口时不需要强制转换。您可以显式地转换回实际的子类型。 (这里可能会发生 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;

© www.soinside.com 2019 - 2024. All rights reserved.