Java ClassCastException,但仍然编译
一位同事向我展示了这段代码,我知道它不起作用(事实上,在运行时抛出Java ClassCastException,但仍然编译,java,casting,Java,Casting,一位同事向我展示了这段代码,我知道它不起作用(事实上,在运行时抛出ClassCastException) 我不知道它为什么编译,因为它是从 java.io.FileInputStream至org.springframework.core.io.InputStreamSource
ClassCastException
)
我不知道它为什么编译,因为它是从
java.io.FileInputStream
至org.springframework.core.io.InputStreamSource它们都没有实现相同的接口,也没有在层次结构中扩展相同的类
try(InputStream文件InputStream=newfileinputstream(“somefile”)){
InputStreamSource文件=(InputStreamSource)文件InputStream;
//一些代码
}捕获(IOE异常){
//一些代码
}
各文件类别的链接:
,
我不知道为什么它会编译
因为它是非
最终引用类型和接口之间的显式转换。引用类型之间的显式转换对编译器说:“看,我(程序员)知道这个转换在运行时是有效的。相信我。”它确实如此。当然,后来在运行时,由于程序员出错,它失败了
不过,编译器不会盲目地信任程序员。详细信息,但如果编译器可以证明强制转换不可能有效,它仍然会拒绝强制转换。但是,在您的情况下,它不能这样做,因为InputStreamSource
是一个接口,FileInputStream
是一个非final
类。因此,FileInputStream
很可能是指实现InputStreamSource
的某个子类对象。(当然,我们可以通过查看它来判断它不是,因为它只是设置为newfileinputstream
的结果。但是编译器看起来并没有那么难,它只关心强制转换中涉及的类型。)
我不知道为什么它会编译
因为它是非最终引用类型和接口之间的显式转换。引用类型之间的显式转换对编译器说:“看,我(程序员)知道这个转换在运行时是有效的。相信我。”它确实如此。当然,后来在运行时,由于程序员出错,它失败了
不过,编译器不会盲目地信任程序员。详细信息,但如果编译器可以证明强制转换不可能有效,它仍然会拒绝强制转换。但是,在您的情况下,它不能这样做,因为
InputStreamSource
是一个接口,FileInputStream
是一个非final
类。因此,FileInputStream
很可能是指实现InputStreamSource
的某个子类对象。(当然,我们可以通过查看它来判断它不是,因为它只是设置为newfileinputstream
的结果。但是编译器看起来并不难,它只关心强制转换中涉及的类型。)因为它是显式强制转换。编译器相信该强制转换在运行时是有效的,因此如果不是这样,它将失败。因为它是显式强制转换。编译器相信您,强制转换在运行时是有效的,因此如果不是这种情况,它将失败。编译器可能重复的可能重复并不总是盲目地信任程序员:如果原始类和目标类不相关,它将不允许插入强制转换。例如,如果原始类是final
。示例:如果声明的Long var=1L
,然后是Integer var2=(Integer)var代码>将不会编译。它必须是Integer var2=(Integer)(Number)var代码>(在运行时仍然会失败,ofc).@M.Prokhorov-谢谢!!我查看了JLS§5.5,因为我想我记得有限制。修复了,我想。编译器允许你这么做,因为它可能是实现接口的某个类。我做了一些测试并编译了它(显然它在运行时失败)。非常感谢。编译器并不总是盲目地信任程序员:如果原始类和目标类不相关,它将不允许插入强制转换。例如,如果原始类是final
。示例:如果声明的Long var=1L
,然后是Integer var2=(Integer)var代码>将不会编译。它必须是Integer var2=(Integer)(Number)var代码>(在运行时仍然会失败,ofc).@M.Prokhorov-谢谢!!我查看了JLS§5.5,因为我想我记得有限制。修复了,我想。编译器允许你这么做,因为它可能是实现接口的某个类。我做了一些测试并编译了它(显然它在运行时失败)。非常感谢你。