为什么在转换为不相关的接口时会编译?
interface Printable {} class BlackInk {} public class Main { public static void main(String args[]) { Printable printable = null; BlackInk blackInk = new BlackInk(); printable = (Printable)blackInk; } }
如果编译并运行前面的代码,则结果是printable = (Printable)blackInk;
的ClassCastException printable = (Printable)blackInk;
。 但是,如果将Printable更改为类,则不会编译,因为blackInk无法强制转换为Printable。 当Printable是一个接口时,为什么要编译?
编译器不知道这不起作用:你可以有一个实现Printable的BlackInk子类。 然后演员会很好。
在编译器知道它不起作用的情况下,您将收到错误。
例如,如果你使BlackInk成为final
(这样就没有子类)就会出错。
根据java语言规范部分:5.5.1 引用类型转换 :
对于编译时引用类型S
(源)和编译类型引用类型T
(目标); 在将转换从S
转换为T
, 如果S
是class
Type
-
如果
T
是Class
类型 :- 那么
T
是S
的子类型或S
是T
的子类型。 否则,发生编译时错误。 -
如果存在
T
的超类型X
和S
的超类型Y
,使得X
和Y
都可certificate是不同的参数化类型,并且X
和Y
的擦除相同,则发生编译时错误 。class S{} class T extends S{} //// S s = new S(); T t = (T)s; // run time ClassCastException will happen but no compile time error
- 那么
-
如果
T
是Interface
类型 :- 如果
S
不是final
类,那么,如果存在T
的超类型X
和S
的超类型Y
,使得X
和Y
都可certificate是不同的参数化类型,并且X
和Y
的擦除是相同的,发生编译时错误 。 否则,强制转换在编译时总是合法的( 因为即使S
没有实现T
,S
的子类也可能 ) - 如果S是最终类,那么S必须实现T,否则会发生编译时错误。
- 如果
这适用于您的情况,即使在编译时检测到类转换,也会在runtime
检测到接口转换。
类型转换在run time
发生(记住运行时多态)。 在编译时编译器没有看到代码和编译有任何问题,并且在运行时它尝试将cast blackink
键入printable
,并且无法执行此操作因为blackink
不实现printable
,因此错误。
- 引起:java.lang.ClassCastException:java.sql.Timestamp无法强制转换为java.sql.Date
- java.lang.ClassCastException的含义:someClass与someClass不兼容
- MyClass无法强制转换为java.lang.Comparable:java.lang.ClassCastException
- 附加对象OutputStream时的ClassCastException
- Javagenerics中不会抛出ClassCastException
- 签名小程序和服务器端控制器之间的通信
- ClassCastException与“无法强制转换”编译错误
- 如何构建同一个加载不同类加载器的两个实例?
- Android java.lang.ClassCastException:android.widget.RelativeLayout无法强制转换为android.widget.EditText