Java转换导致运行时错误而不是编译错误

czc*_*ong 4 java

以下代码段将导致运行时:

class Vehicle {
    public void printSound() {
        System.out.print("vehicle");
    }
}

class Car extends Vehicle {
    public void printSound() {
        System.out.print("car");
    }
}

class Bike extends Vehicle {
    public void printSound() {
        System.out.print("bike");
    }
}

public class Test {
    public static void main(String[] args) {
        Vehicle v = new Car();
        Bike b = (Bike) v;

        v.printSound();
        b.printSound();
    }   
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么会导致运行时错误而不是编译错误?难道编译器不应该知道'v'已经是'Car'并且不能被投入'Bike'吗?

dle*_*lev 9

从理论上讲,编译器可能会对自己说:" v是局部变量,被指定为a Car.在尝试强制转换之前,Bike它没有改变它的值,也没有办法Car成为成功投了Bike.因此,这是一个错误."

但是,我知道没有Java编译器可以为您进行分析.在最简单的情况下,这真的是值得的.相反,行为是编译器看到强制转换,以及可以将a转换Vehicle为a的原因Bike,因此它允许它.

一般来说,这就是一个强制转换的意思:它告诉编译器即使这个赋值可能会失败,你也很确定它不会.作为允许代码编译的交换,您承担运行时异常的风险.


MBy*_*ByD 5

从超类进行转换可能会起作用,因此可以(在编译期间)进行转换。不允许从完全不同的类进行转换,例如:

Integer a = 1;
String b = (String)a; // compile error
String b = (String)(Object)a; // runtime error
Run Code Online (Sandbox Code Playgroud)