instanceof关键字及其新特性
当在程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生 ClassCastException 异常,因此在执行向下转型之前需要养成一个良好的习惯,就是判断父类对象是否为子类对象的实例。这个判断通常使用 instanceof 关键字来完成。可以使用 instanceof 关键字判断是否一个类实现了某个接口(接口会在第7.8节中进行讲解),也可以用它来判断一个实例对象是否属于一个类。
instanceof 的语法格式如下:
myobject instanceof ExampleClass
-
myobject:某类的对象引用。
-
ExampleClass:某个类。
使用 instanceof 关键字的表达式返回值为布尔值。如果返回值为 true,则说明 myobject 对象为 ExampleClass 的实例对象;如果返回值为 false,则说明 myobject 对象不是 ExampleClass 的实例对象。
instanceof 是 Java 语言的关键字,Java 语言中的关键字都为小写。 |
下面来看一个向下转型与 instanceof 关键字结合的例子。
【例7.7】分析几何图形之间的继承关系(实例位置:资源包\TM\sl\7\7)
创建 Quadrangle 四边形类、Square 正方形类和 Circular 圆形类。其中,Square 类继承 Quadrangle 类,在主方法中分别创建这些类的对象,然后使用 instanceof 关键字判断它们的类型并输出结果。
class Quadrangle { }
class Square extends Quadrangle { }
class Circular { }
public class Demo5 {
public static void main(String args[]) {
Quadrangle q = new Quadrangle(); // 四边形对象
Square s = new Square(); // 正方形对象
// 判断四边形是否为正方形的子类
System.out.println(q instanceof Square);
// 判断正方形是否为四边形的子类
System.out.println(s instanceof Quadrangle);
// 由于正方形是否为圆形的子类
System.out.println(q instanceof Circular);
}
}
本实例在运行之前,Eclipse 就会报出如图7.5所示的编译错误。

由于四边形类与圆形类没有继承关系,因此二者不能使用 instanceof 关键字进行比较,否则会发生 “不兼容” 错误。如果删除或注释掉这行代码,则运行结果如下:
false
true
Java 14 为 instanceof 关键字提供了一个新特性:instanceof 模式匹配。那么,应该如何理解 “instanceof模式匹配” 呢?下面通过一个示例予以说明。
已知现有一个表示 “平行四边形类” 的 Quadrangle 类、一个表示 “圆环类” 的 Circular 类和一个用于测试 Test 类。在 Quadrangle 类和 Circular 类中都包含一个用于获取图形类别的 getCategory() 方法。在 Test 类中包含一个静态的、参数为 Object 类对象的 testGraphics() 方法,该方法用于检验 Object 类对象属于 “平行四边形类”,还是属于 “圆环类”。代码如下:
class Quadrangle {
public String getCategory() {
return "我属于平行四边形类";
}
}
class Circular {
public String getCategory() {
return "我属于圆环类";
}
}
public class Test {
public static void main(String args[]) {
Circular c = new Circular();
testGraphics(c);
}
static void testGraphics(Object obj) {
if (obj instanceof Quadrangle) {
Quadrangle q = (Quadrangle) obj;
System.out.println(q.getCategory());
} else if (obj instanceof Circular) {
Circular c = (Circular) obj;
System.out.println(c.getCategory());
}
}
}
运行结果如下:
我属于圆环类
从上述代码中不难看出,instanceof 确认成功后,还需要转换 Object 类对象的数据类型,才能调用相应类中的方法。使用 “instanceof模式匹配” 可以简化这个过程。关键代码如下:
static void testGraphics(Object obj) {
if (obj instanceof Quadrangle q) {
System.out.println(q.getCategory());
} else if (obj instanceof Circular c) {
System.out.println(c.getCategory());
}
}
也就是说,使用 “instanceof模式匹配” 省去了 “转换Object类对象的数据类型” 的步骤。此外,instanceof 模式匹配的使用对象还被限定了作用域范围,使得程序更加安全。
编程训练(答案位置:资源包\TM\sl\7\编程训练)
【训练7】鸡是不是鸟? 判断“鸡是不是鸟”并阐明依据(因为鸡是鸟的子类,所以鸡是鸟)。
【训练8】总统是不是公务员? 通过instanceof判断总统是不是公务员,并输出公务员和总统的主要工作。