如何在 Java 中检查对象是否为类的实例

JavaJavaBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个实验中,你将学习如何在 Java 中使用 instanceof 关键字来检查一个对象是否是特定类或接口的实例。我们将探讨它的基本用法,测试它在处理子类时的行为,并了解它如何处理空对象。

通过实际操作示例,你将获得使用 instanceof 进行运行时类型检查的实践经验,这是面向对象编程中的一个基本概念。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/BasicSyntaxGroup(["Basic Syntax"]) java/BasicSyntaxGroup -.-> java/if_else("If...Else") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("Classes/Objects") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/oop("OOP") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/inheritance("Inheritance") subgraph Lab Skills java/if_else -.-> lab-560010{{"如何在 Java 中检查对象是否为类的实例"}} java/classes_objects -.-> lab-560010{{"如何在 Java 中检查对象是否为类的实例"}} java/oop -.-> lab-560010{{"如何在 Java 中检查对象是否为类的实例"}} java/inheritance -.-> lab-560010{{"如何在 Java 中检查对象是否为类的实例"}} end

使用 instanceof 进行类检查

在这一步中,我们将探索 Java 中的 instanceof 关键字。instanceof 关键字用于测试一个对象是否是某个特定类的实例,或者是否实现了某个特定接口。它是在运行时检查对象类型的有用工具。

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

  1. 打开 WebIDE,确保你位于 ~/project 目录下。你可以通过查看终端提示符,或者输入 pwd 并按回车键来确认。

  2. ~/project 目录下创建一个名为 TypeCheck.java 的新 Java 文件。你可以通过在左侧的文件资源管理器中右键单击,选择“新建文件”,然后输入 TypeCheck.java 来完成。

  3. 在编辑器中打开 TypeCheck.java 文件,并粘贴以下代码:

    class Animal {
        // Base class
    }
    
    class Dog extends Animal {
        // Subclass of Animal
    }
    
    class Cat extends Animal {
        // Subclass of Animal
    }
    
    public class TypeCheck {
        public static void main(String[] args) {
            Animal myAnimal = new Dog();
    
            // Check if myAnimal is an instance of Dog
            if (myAnimal instanceof Dog) {
                System.out.println("myAnimal is an instance of Dog");
            } else {
                System.out.println("myAnimal is not an instance of Dog");
            }
    
            // Check if myAnimal is an instance of Cat
            if (myAnimal instanceof Cat) {
                System.out.println("myAnimal is an instance of Cat");
            } else {
                System.out.println("myAnimal is not an instance of Cat");
            }
    
            // Check if myAnimal is an instance of Animal
            if (myAnimal instanceof Animal) {
                System.out.println("myAnimal is an instance of Animal");
            } else {
                System.out.println("myAnimal is not an instance of Animal");
            }
        }
    }

    在这段代码中:

    • 我们定义了一个基类 Animal 和两个子类 DogCat
    • main 方法中,我们创建了一个 Animal 类型的变量 myAnimal,并将一个 Dog 对象赋值给它。这是可行的,因为 DogAnimal 的一种类型。
    • 然后,我们使用 instanceof 关键字来检查 myAnimal 是否是 DogCatAnimal 的实例。
  4. 保存 TypeCheck.java 文件(Ctrl+S 或 Cmd+S)。

  5. 通过打开 WebIDE 底部的终端并运行以下命令来编译 Java 程序:

    javac TypeCheck.java

    如果没有错误,此命令将在 ~/project 目录下创建 TypeCheck.classAnimal.classDog.classCat.class 文件。

  6. 使用以下命令运行编译后的程序:

    java TypeCheck

    你应该会看到类似于以下的输出:

    myAnimal is an instance of Dog
    myAnimal is not an instance of Cat
    myAnimal is an instance of Animal

    这个输出证实了持有 Dog 对象的 myAnimal 确实是 Dog 的实例,也是其超类 Animal 的实例,但不是 Cat 的实例。

你已经成功地使用 instanceof 关键字在 Java 中检查了对象的类型。在下一步中,我们将探索 instanceof 在处理子类时的行为。

子类测试

在上一步中,我们了解到一个对象既被视为其自身类的实例,也被视为其超类的实例。接下来,让我们进一步探索 instanceof 在不同对象类型及其子类中的工作方式。

我们将修改现有的 TypeCheck.java 文件,用一个 Cat 对象来测试 instanceof

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

  2. 找到 main 方法,并在现有的 myAnimal 检查代码之后添加以下代码行:

            System.out.println("\n--- Testing with a Cat object ---");
            Animal anotherAnimal = new Cat();
    
            // Check if anotherAnimal is an instance of Dog
            if (anotherAnimal instanceof Dog) {
                System.out.println("anotherAnimal is an instance of Dog");
            } else {
                System.out.println("anotherAnimal is not an instance of Dog");
            }
    
            // Check if anotherAnimal is an instance of Cat
            if (anotherAnimal instanceof Cat) {
                System.out.println("anotherAnimal is an instance of Cat");
            } else {
                System.out.println("anotherAnimal is not an instance of Cat");
            }
    
            // Check if anotherAnimal is an instance of Animal
            if (anotherAnimal instanceof Animal) {
                System.out.println("anotherAnimal is an instance of Animal");
            } else {
                System.out.println("anotherAnimal is not an instance of Animal");
            }

    现在,完整的 TypeCheck.java 文件应该如下所示:

    class Animal {
        // Base class
    }
    
    class Dog extends Animal {
        // Subclass of Animal
    }
    
    class Cat extends Animal {
        // Subclass of Animal
    }
    
    public class TypeCheck {
        public static void main(String[] args) {
            Animal myAnimal = new Dog();
    
            // Check if myAnimal is an instance of Dog
            if (myAnimal instanceof Dog) {
                System.out.println("myAnimal is an instance of Dog");
            } else {
                System.out.println("myAnimal is not an instance of Dog");
            }
    
            // Check if myAnimal is an instance of Cat
            if (myAnimal instanceof Cat) {
                System.out.println("myAnimal is an instance of Cat");
            } else {
                System.out.println("myAnimal is not an instance of Cat");
            }
    
            // Check if myAnimal is an instance of Animal
            if (myAnimal instanceof Animal) {
                System.out.println("myAnimal is an instance of Animal");
            } else {
                System.out.println("myAnimal is not an instance of Animal");
            }
    
            System.out.println("\n--- Testing with a Cat object ---");
            Animal anotherAnimal = new Cat();
    
            // Check if anotherAnimal is an instance of Dog
            if (anotherAnimal instanceof Dog) {
                System.out.println("anotherAnimal is an instance of Dog");
            } else {
                System.out.println("anotherAnimal is not an instance of Dog");
            }
    
            // Check if anotherAnimal is an instance of Cat
            if (anotherAnimal instanceof Cat) {
                System.out.println("anotherAnimal is an instance of Cat");
            } else {
                System.out.println("anotherAnimal is not an instance of Cat");
            }
    
            // Check if anotherAnimal is an instance of Animal
            if (anotherAnimal instanceof Animal) {
                System.out.println("anotherAnimal is an instance of Animal");
            } else {
                System.out.println("anotherAnimal is not an instance of Animal");
            }
        }
    }
  3. 保存修改后的 TypeCheck.java 文件。

  4. 在终端中再次编译程序:

    javac TypeCheck.java
  5. 运行编译后的程序:

    java TypeCheck

    你现在应该会看到类似以下的输出:

    myAnimal is an instance of Dog
    myAnimal is not an instance of Cat
    myAnimal is an instance of Animal
    
    --- Testing with a Cat object ---
    anotherAnimal is not an instance of Dog
    anotherAnimal is an instance of Cat
    anotherAnimal is an instance of Animal

    这个输出表明,持有 Cat 对象的 anotherAnimalCatAnimal 的实例,但不是 Dog 的实例。这进一步强化了 instanceof 会检查对象的实际类型及其继承层次结构的概念。

你已经成功地使用不同的子类对象测试了 instanceof 关键字。在下一步中,我们将了解 instanceof 在处理 null 对象时的行为。

对空对象进行验证

在这最后一步中,我们将研究当被测试的对象为 null 时,instanceof 关键字的行为。理解这一点对于避免 Java 程序中可能出现的错误非常重要。

我们将再次修改 TypeCheck.java 文件,加入对 null 对象的测试。

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

  2. main 方法的末尾,即之前的测试代码之后,添加以下代码行:

            System.out.println("\n--- Testing with a null object ---");
            Animal nullAnimal = null;
    
            // Check if nullAnimal is an instance of Dog
            if (nullAnimal instanceof Dog) {
                System.out.println("nullAnimal is an instance of Dog");
            } else {
                System.out.println("nullAnimal is not an instance of Dog");
            }
    
            // Check if nullAnimal is an instance of Animal
            if (nullAnimal instanceof Animal) {
                System.out.println("nullAnimal is an instance of Animal");
            } else {
                System.out.println("nullAnimal is not an instance of Animal");
            }

    现在,完整的 TypeCheck.java 文件应如下所示:

    class Animal {
        // Base class
    }
    
    class Dog extends Animal {
        // Subclass of Animal
    }
    
    class Cat extends Animal {
        // Subclass of Animal
    }
    
    public class TypeCheck {
        public static void main(String[] args) {
            Animal myAnimal = new Dog();
    
            // Check if myAnimal is an instance of Dog
            if (myAnimal instanceof Dog) {
                System.out.println("myAnimal is an instance of Dog");
            } else {
                System.out.println("myAnimal is not an instance of Dog");
            }
    
            // Check if myAnimal is an instance of Cat
            if (myAnimal instanceof Cat) {
                System.out.println("myAnimal is not an instance of Cat");
            } else {
                System.out.println("myAnimal is not an instance of Cat");
            }
    
            // Check if myAnimal is an instance of Animal
            if (myAnimal instanceof Animal) {
                System.out.println("myAnimal is an instance of Animal");
            } else {
                System.out.println("myAnimal is not an instance of Animal");
            }
    
            System.out.println("\n--- Testing with a Cat object ---");
            Animal anotherAnimal = new Cat();
    
            // Check if anotherAnimal is an instance of Dog
            if (anotherAnimal instanceof Dog) {
                System.out.println("anotherAnimal is not an instance of Dog");
            } else {
                System.out.println("anotherAnimal is not an instance of Dog");
            }
    
            // Check if anotherAnimal is an instance of Cat
            if (anotherAnimal instanceof Cat) {
                System.out.println("anotherAnimal is an instance of Cat");
            } else {
                System.out.println("anotherAnimal is an instance of Cat");
            }
    
            // Check if anotherAnimal is an instance of Animal
            if (anotherAnimal instanceof Animal) {
                System.out.println("anotherAnimal is an instance of Animal");
            } else {
                System.out.println("anotherAnimal is an instance of Animal");
            }
    
            System.out.println("\n--- Testing with a null object ---");
            Animal nullAnimal = null;
    
            // Check if nullAnimal is an instance of Dog
            if (nullAnimal instanceof Dog) {
                System.out.println("nullAnimal is an instance of Dog");
            } else {
                System.out.println("nullAnimal is not an instance of Dog");
            }
    
            // Check if nullAnimal is an instance of Animal
            if (nullAnimal instanceof Animal) {
                System.out.println("nullAnimal is an instance of Animal");
            } else {
                System.out.println("nullAnimal is not an instance of Animal");
            }
        }
    }
  3. 保存修改后的 TypeCheck.java 文件。

  4. 在终端中编译程序:

    javac TypeCheck.java
  5. 运行编译后的程序:

    java TypeCheck

    你应该会看到类似以下的输出:

    myAnimal is an instance of Dog
    myAnimal is not an instance of Cat
    myAnimal is an instance of Animal
    
    --- Testing with a Cat object ---
    anotherAnimal is not an instance of Dog
    anotherAnimal is an instance of Cat
    anotherAnimal is an instance of Animal
    
    --- Testing with a null object ---
    nullAnimal is not an instance of Dog
    nullAnimal is not an instance of Animal

    从输出中可以看出,当使用 instanceof 测试的对象为 null 时,结果始终为 false。在使用 instanceof 时记住这一点至关重要,可避免意外行为或 NullPointerException

你已成功验证了 instanceof 关键字在处理 null 对象时的行为。至此,我们对 instanceof 关键字的探索就结束了。

总结

在本次实验中,我们学习了如何在 Java 中使用 instanceof 关键字来检查一个对象是否是某个特定类的实例,或者是否实现了某个特定接口。我们通过创建一个包含基类和子类的简单程序来演示其用法,然后使用 instanceof 在运行时验证对象的类型。

我们进一步探索了 instanceof 在子类中的行为,证实了一个对象既被视为其自身类的实例,也被视为任何超类的实例。最后,我们研究了 instanceof 应用于空对象时的行为,了解到在这种情况下它总是返回 false