instanceof 运算符
本课属于 Coddy Java 学习旅程的“面向对象编程”单元。第 31 课,共 87 课。
上一课说明了,如果对象实际上不是你要转换成的类型,下转型可能会因 ClassCastException 而失败。instanceof 运算符可以让你在转换前检查对象的类型,从而解决这个问题。
语法很简单:如果对象是该类(或其任意子类)的实例,object instanceof ClassName 就会返回 true:
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark(); // 可以安全地调用 Dog 类特有的方法
}这个检查可以确保类型转换成功,从而避免运行时错误。对于继承层级中的父类型,该运算符也会返回 true:
Dog dog = new Dog();
System.out.println(dog instanceof Dog); // true
System.out.println(dog instanceof Animal); // true
System.out.println(dog instanceof Object); // true从 Java 16 开始,你可以使用模式匹配,一步完成检查和类型转换:
if (animal instanceof Dog dog) {
dog.bark(); // 'dog' 已完成类型转换,可以直接使用
}这种更简洁的语法省去了单独的类型转换语句。请注意,使用 instanceof 检查 null 时会返回 false,因此你不需要单独检查 null。
挑战
简单我们来构建一个车辆检查系统,使用 instanceof 运算符安全地识别和处理不同类型的车辆。你将创建一个车辆类层次结构,并编写代码,在访问车辆的专属功能前检查车辆的实际类型。
你需要将代码分成 4 个文件:
Vehicle.java:创建所有车辆共用的基类。每辆车都有一个model字段(String)。添加一个用于初始化该字段的构造函数、一个 getter 方法getModel(),以及一个打印以下内容的方法inspect():Inspecting vehicle: [model]Car.java:创建一个继承 Vehicle 的类。汽车还有一个额外的numDoors字段(int)。使用super初始化父类。添加一个打印以下内容的方法checkDoors():[model] has [numDoors] doorsMotorcycle.java:创建另一个继承 Vehicle 的类。摩托车有一个hasSidecar字段(boolean)。添加一个方法checkSidecar(),根据布尔值打印[model] has a sidecar或[model] has no sidecar。Main.java:这里就需要用到instanceof了!你会收到 4 个输入:汽车型号、车门数量、摩托车型号,以及是否带有边斗(true/false)。创建一个
Vehicle引用数组,其中包含一辆 Car 和一辆 Motorcycle。然后循环遍历数组,对每辆车执行以下操作:- 调用基类的
inspect()方法 - 使用
instanceof检查它是否是 Car,如果是,就安全地向下转型并调用checkDoors() - 使用
instanceof检查它是否是 Motorcycle,如果是,就安全地向下转型并调用checkSidecar()
- 调用基类的
你会收到 4 个输入:汽车型号(String)、车门数量(int)、摩托车型号(String)以及是否带有边斗(boolean)。
输出应包含 4 行:每辆车都会先显示检查信息,然后显示对应类型的检查结果。instanceof 运算符可以确保你只对 Car 调用 Car 的方法,只对 Motorcycle 调用 Motorcycle 的方法,从而避免 ClassCastException!
亲手试试
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取输入
String carModel = scanner.nextLine();
int numDoors = Integer.parseInt(scanner.nextLine());
String motorcycleModel = scanner.nextLine();
boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
// TODO: 用 carModel 和 numDoors 创建一个 Car 对象
// TODO: 用 motorcycleModel 和 hasSidecar 创建一个 Motorcycle 对象
// TODO: 创建一个包含 Car 和 Motorcycle 的 Vehicle 引用数组
// TODO: 遍历数组,对每辆车执行以下操作:
// 1. 调用 inspect() 方法
// 2. 用 instanceof 检查它是否为 Car,然后向下转型并调用 checkDoors()
// 3. 用 instanceof 检查它是否为 Motorcycle,然后向下转型并调用 checkSidecar()
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Java 在线编译器