试图以下内容:
class Base {
public Base(){
}
}
class Derived extends Base {
}
public class Main
{
public static void main (String[] args)
{
Derived derived = (Derived) new Base();
}
}
Run Code Online (Sandbox Code Playgroud)
导致a CastClassException,但编译成功.对这个问题的评论表明,编译器不可能在new Base()运行时找出什么类型- 但为什么会出现这种情况呢?我知道在其他类型的系统中,编译器总是可以推断出任何表达式的类型,而Java编译器肯定会使用例如lambda表达式进行一些类型推断.在某些时候,new Base()如果要发出正确的字节码,它必须知道什么类型.
是否有一个理论上的限制阻止Java编译器在程序运行之前捕获它,或者它是一个实现选择?
public static void main(String[] args) throws Exception {
Derived derived = (Derived) getObject();
}
public static Base getObject() {
if (Math.random() > 0.5) {
return new Base();
} else {
return new Derived();
}
}
Run Code Online (Sandbox Code Playgroud)
现在怎么办?编译器如何知道?编译器(大部分)仅限于静态信息.对象的类型是动态信息.