如何在 Java 中检查对象是否为特定类型

JavaBeginner
立即练习

介绍

在这个实验中,你将学习如何使用 instanceof 运算符来检查一个对象是否为 Java 中的特定类型。你将从理解 instanceof 在不同类(包括继承关系的类)中的基本用法开始。

然后,你将使用各种类类型测试 instanceof 运算符,并探究它在处理子类和超类时的行为。最后,你将学习在使用 instanceof 时如何处理空对象,以避免潜在的错误。

使用 instanceof 运算符

在这一步中,你将学习 Java 中的 instanceof 运算符。instanceof 运算符用于测试一个对象是否是某个特定类的实例,或者是否实现了某个特定接口。它是在运行时检查对象类型的有用工具。

让我们创建一个简单的 Java 程序来演示 instanceof 运算符的工作原理。

  1. 如果 HelloJava.java 文件尚未在 WebIDE 编辑器中打开,请打开它。

  2. 将文件的全部内容替换为以下代码:

    class Animal {
        public void makeSound() {
            System.out.println("Generic animal sound");
        }
    }
    
    class Dog extends Animal {
        public void makeSound() {
            System.out.println("Woof!");
        }
    }
    
    class Cat extends Animal {
        public void makeSound() {
            System.out.println("Meow!");
        }
    }
    
    public class HelloJava {
        public static void main(String[] args) {
            Animal myAnimal = new Dog();
    
            if (myAnimal instanceof Dog) {
                System.out.println("myAnimal is an instance of Dog");
            }
    
            if (myAnimal instanceof Cat) {
                System.out.println("myAnimal is an instance of Cat");
            }
    
            if (myAnimal instanceof Animal) {
                System.out.println("myAnimal is an instance of Animal");
            }
        }
    }
    

    在这段代码中:

    • 我们定义了一个基类 Animal 以及两个子类 Dog 和 Cat。
    • 在 main 方法中,我们创建了一个 Animal 类型的变量 myAnimal,并将一个 Dog 对象赋值给它。
    • 然后,我们使用 instanceof 运算符来检查 myAnimal 是否是 Dog、Cat 和 Animal 的实例。
  3. 保存文件(Ctrl+S 或 Cmd+S)。

  4. 在终端中使用 javac 命令编译程序:

    javac HelloJava.java
    
  5. 使用 java 命令运行编译后的程序:

    java HelloJava
    

    你应该会看到输出,表明哪些 instanceof 检查返回了 true。

    myAnimal is an instance of Dog
    myAnimal is an instance of Animal
    

    如你所见,myAnimal 是 Dog 的实例(因为我们创建了一个 Dog 对象),同时也是 Animal 的实例(因为 Dog 是 Animal 的子类)。它不是 Cat 的实例。

使用不同类进行测试

在上一步中,你已经了解了 instanceof 在子类和其超类之间的工作方式。现在,让我们来探究一下当针对不同的、无关联的类进行测试时,它的表现如何。

我们将修改现有的 HelloJava.java 文件,添加另一个类,并使用不同类型的对象来测试 instanceof 运算符。

  1. 在 WebIDE 编辑器中打开 HelloJava.java 文件。

  2. 在文件中添加一个名为 Car 的新类。你可以将这个类的定义添加在 Animal、Dog 和 Cat 类之前或之后,但要放在 HelloJava 类之外。

    class Car {
        public void drive() {
            System.out.println("Driving a car");
        }
    }
    
  3. 现在,让我们修改 HelloJava 类中的 main 方法,创建一个 Car 对象并测试 instanceof 运算符。将 main 方法更新为如下所示:

    public class HelloJava {
        public static void main(String[] args) {
            Animal myAnimal = new Dog();
            Car myCar = new Car();
    
            if (myAnimal instanceof Dog) {
                System.out.println("myAnimal is an instance of Dog");
            }
    
            if (myAnimal instanceof Cat) {
                System.out.println("myAnimal is an instance of Cat");
            }
    
            if (myAnimal instanceof Animal) {
                System.out.println("myAnimal is an instance of Animal");
            }
    
            System.out.println("--- Testing Car object ---");
    
            if (myCar instanceof Car) {
                System.out.println("myCar is an instance of Car");
            }
    
            if (myCar instanceof Animal) {
                System.out.println("myCar is an instance of Animal");
            }
        }
    }
    

    我们添加了一个新的 Car 对象 myCar,并对它进行了针对 Car 和 Animal 的 instanceof 检查。

  4. 保存文件(Ctrl+S 或 Cmd+S)。

  5. 编译修改后的程序:

    javac HelloJava.java
    
  6. 运行程序:

    java HelloJava
    

    观察输出。你应该会看到上一步的结果,接着是对 Car 对象进行新检查的结果。

    myAnimal is an instance of Dog
    myAnimal is an instance of Animal
    --- Testing Car object ---
    myCar is an instance of Car
    

    这个输出证实了 myCar 是 Car 的实例,但它不是 Animal 的实例,因为 Car 并没有继承自 Animal。instanceof 运算符能够正确识别对象和类之间的类型关系(或不存在这种关系)。

处理空对象

在这最后一步中,我们将探究 instanceof 运算符在处理 null 对象时的表现。理解这一点对于避免程序中出现意外错误至关重要。

在 Java 中,null 引用意味着一个变量不指向任何对象。当你将 instanceof 运算符与 null 引用一起使用时,它总是会返回 false。这是该运算符内置的安全特性。

让我们最后一次修改 HelloJava.java 文件,加入一个 null 对象并测试 instanceof 运算符。

  1. 在 WebIDE 编辑器中打开 HelloJava.java 文件。

  2. 修改 HelloJava 类中的 main 方法,加入一个 null 的 Animal 引用并进行测试。将 main 方法更新为如下所示:

    class Animal {
        public void makeSound() {
            System.out.println("Generic animal sound");
        }
    }
    
    class Dog extends Animal {
        public void makeSound() {
            System.out.println("Woof!");
        }
    }
    
    class Cat extends Animal {
        public void makeSound() {
            System.out.println("Meow!");
        }
    }
    
    class Car {
        public void drive() {
            System.out.println("Driving a car");
        }
    }
    
    public class HelloJava {
        public static void main(String[] args) {
            Animal myAnimal = new Dog();
            Car myCar = new Car();
            Animal nullAnimal = null; // Declare a null Animal reference
    
            if (myAnimal instanceof Dog) {
                System.out.println("myAnimal is an instance of Dog");
            }
    
            if (myAnimal instanceof Cat) {
                System.out.println("myAnimal is an instance of Cat");
            }
    
            if (myAnimal instanceof Animal) {
                System.out.println("myAnimal is an instance of Animal");
            }
    
            System.out.println("--- Testing Car object ---");
    
            if (myCar instanceof Car) {
                System.out.println("myCar is an instance of Car");
            }
    
            if (myCar instanceof Animal) {
                System.out.println("myCar is an instance of Animal");
            }
    
            System.out.println("--- Testing null object ---");
    
            if (nullAnimal instanceof Animal) {
                System.out.println("nullAnimal is an instance of Animal");
            }
    
            if (nullAnimal instanceof Dog) {
                System.out.println("nullAnimal is an instance of Dog");
            }
        }
    }
    

    我们添加了一个新的 Animal 变量 nullAnimal 并将其初始化为 null。然后对它进行 instanceof 检查。

  3. 保存文件(Ctrl+S 或 Cmd+S)。

  4. 编译程序:

    javac HelloJava.java
    
  5. 运行程序:

    java HelloJava
    

    观察输出。你应该会看到之前步骤的结果,接着是对 nullAnimal 进行检查的结果。

    myAnimal is an instance of Dog
    myAnimal is an instance of Animal
    --- Testing Car object ---
    myCar is an instance of Car
    --- Testing null object ---
    

    注意,nullAnimal 的 if 代码块内的行没有被打印出来。这是因为 nullAnimal instanceof Animal 和 nullAnimal instanceof Dog 都计算为 false。这表明 instanceof 运算符通过返回 false 正确处理了 null 引用。

理解 instanceof 如何处理 null 对于编写健壮的 Java 代码、避免 NullPointerException 错误至关重要。

总结

在这个实验中,你学习了如何在 Java 中使用 instanceof 运算符来检查一个对象是否属于特定类型。你练习了在不同的类(包括基类及其子类)中使用 instanceof,以确定对象的运行时类型。你还探究了在针对对象的实际类、其超类以及不相关的类进行检查时,instanceof 的表现。