Java语言对象引用的缩小和扩大
示例
如:中将基类的实例强制转换为子类b=(B)a;称为缩小(因为您试图将基类对象缩小为更具体的类对象),并且需要显式的类型转换。
将子类的实例转换为基类,如:Aa=b;中所示,这称为扩展,不需要类型转换。
为了说明,请考虑以下类声明和测试代码:
class Vehicle { } class Car extends Vehicle { } class Truck extends Vehicle { } class MotorCycle extends Vehicle { } class Test { public static void main(String[] args) { Vehicle vehicle = new Car(); Car car = new Car(); vehicle = car; //有效,不需要强制转换 Car c = vehicle //无效 Car c = (Car) vehicle; //valid } }
该语句是有效的Java语句。的每个实例也是。因此,该分配是合法的,不需要显式的类型转换。Vehiclevehicle=newCar();CarVehicle
另一方面,Carc=vehicle;是无效的。vehicle变量的静态类型表示该变量Vehicle可以引用的实例Car卡车,摩托车,oranyothercurrentorfuturesubclassof车辆.(Orindeed,aninstanceof车辆itself,sincewedidnotdeclareitasan抽象class.)Theassignmentcannotbeallowed,sincethatmightleadto汽车referringtoa卡车实例。
为了防止这种情况,我们需要添加一个显式的类型转换:
Car c = (Car) vehicle;
类型转换告诉编译器我们期望的值vehicle是的Car或的子类Car。如有必要,编译器将插入代码以执行运行时类型检查。如果检查失败,则在ClassCastException执行代码时将引发a。
请注意,并非所有类型转换都有效。例如:
String s = (String) vehicle; //无效
Java编译器知道与类型兼容的实例Vehicle永远不会与类型兼容String。类型转换永远不会成功,而JLS要求这样做会导致编译错误。