10
interface Printable {}
class BlackInk {}

public class Main {
    public static void main(String args[]) {
        Printable printable = null;
        BlackInk blackInk = new BlackInk();
        printable = (Printable)blackInk;
    }
}

如果前面的代码编译并运行,结果是 ClassCastException at printable = (Printable)blackInk;。但是,如果将 Printable 更改为一个类,它不会编译,因为 blackInk 不能强制转换为 Printable。为什么当 Printable 是接口时它会编译?

4

3 回答 3

19

编译器不知道这是行不通的:你可以有一个 BlackInk 的子类来实现 Printable。那么演员阵容就好了。

在编译器知道它不起作用的情况下,你会得到一个错误。

例如,如果你制作 BlackInk final(这样就不会有子类)你会得到一个错误。

于 2013-11-06T23:21:58.390 回答
13

根据java语言规范部分:5.5.1 Reference Type Casting

对于一个编译时引用类型S(源)和一个编译类型引用类型T(目标);S从to转换时TIfS是一个class类型

  • 如果TClass类型

    1. 那么要么T是 的子类型,S 要么 S是 的子类型T。否则,会发生编译时错误。
    2. 如果存在 的超类型和 的超类型X,使得两者和可证明是不同的参数化类型,并且 和 的擦除相同,则发生编译时错误TYSXYXY

      class S{}
      
       class T extends S{}
        ////
      
        S s = new S();
        T t = (T)s; // run time ClassCastException will happen but no compile time error
      
  • 如果TInterface类型

    1. 如果S不是一个final类,那么,如果存在 的超类型和 的超类型X,使得两者和可证明是不同的参数化类型,并且 和 的擦除相同,则会发生编译时错误。否则,强制转换在编译时总是合法的(因为即使没有实现,也是可能的子类)TYSXYXYSTS
    2. 如果 S 是最终类,则 S 必须实现 T,否则会发生编译时错误。

对于您的情况,即使在编译时检测到类转换,也会在runtime.

于 2013-11-06T23:35:14.797 回答
1

Type casting happens at run time(remember run time polymorphism). At compile time compiler doesn't see anything wrong with the code and compiles and at run time it tries to type cast blackink to printable and is unable to do so as blackink doesn't implement printable , hence the error.

于 2013-11-06T23:24:49.253 回答