Menu
Coddy logo textTech

Der instanceof-Operator

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy — Lektion 31 von 87.

Die vorherige Lektion hat gezeigt, dass Downcasting mit einer ClassCastException fehlschlagen kann, wenn das Objekt nicht tatsächlich der Typ ist, in den Sie umwandeln. Der instanceof-Operator löst dies, indem er Sie den Typ eines Objekts vor der Umwandlung prüfen lässt.

Die Syntax ist unkompliziert: object instanceof ClassName gibt true zurück, wenn das Objekt eine Instanz dieser Klasse (oder einer ihrer Unterklassen) ist:

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Sicherer Aufruf von Dog-spezifischen Methoden
}

Diese Prüfung verhindert Laufzeitfehler, indem sie sicherstellt, dass die Typumwandlung erfolgreich sein wird. Der Operator gibt auch true für Basistypen in der Hierarchie zurück:

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

Seit Java 16 können Sie die Prüfung und den Cast in einem Schritt mittels Pattern Matching kombinieren:

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' ist bereits gecastet und einsatzbereit
}

Diese sauberere Syntax macht die separate Cast-Zeile überflüssig. Beachten Sie, dass instanceof den Wert false zurückgibt, wenn es gegen null geprüft wird, sodass Sie keine separate Null-Prüfung benötigen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Fahrzeuginspektionssystem bauen, das den instanceof-Operator verwendet, um verschiedene Fahrzeugtypen sicher zu identifizieren und zu handhaben. Sie werden eine Hierarchie von Fahrzeugen erstellen und Code schreiben, der den tatsächlichen Typ jedes Fahrzeugs prüft, bevor auf seine spezialisierten Funktionen zugegriffen wird.

Sie werden Ihren Code in vier Dateien organisieren:

  • Vehicle.java: Erstellen Sie die Basisklasse, die alle Fahrzeuge gemeinsam haben. Jedes Fahrzeug hat ein model-Feld (String). Fügen Sie einen Konstruktor zur Initialisierung, eine Getter-Methode getModel() und eine Methode inspect() hinzu, die Folgendes ausgibt: "Inspecting vehicle: " + model
  • Car.java: Erstellen Sie eine Klasse, die Vehicle erweitert. Autos haben ein zusätzliches numDoors-Feld (int). Verwenden Sie super für die Initialisierung der Elternklasse. Fügen Sie eine Methode checkDoors() hinzu, die Folgendes ausgibt: getModel() + " has " + numDoors + " doors"
  • Motorcycle.java: Erstellen Sie eine weitere Klasse, die Vehicle erweitert. Motorräder haben ein hasSidecar-Feld (boolean). Fügen Sie eine Methode checkSidecar() hinzu, die je nach Boolean-Wert entweder getModel() + " has a sidecar" oder getModel() + " has no sidecar" ausgibt.
  • Main.java: Hier wird instanceof unverzichtbar! Sie erhalten vier Eingaben: ein Automodell, die Anzahl der Türen, ein Motorradmodell und ob es einen Beiwagen hat (true/false).

    Erstellen Sie ein Array von Vehicle-Referenzen, das ein Car und ein Motorcycle enthält. Durchlaufen Sie dann das Array in einer Schleife und für jedes Fahrzeug:

    • Rufen Sie die Basis-Methode inspect() auf
    • Verwenden Sie instanceof, um zu prüfen, ob es ein Car ist – wenn ja, führen Sie einen sicheren Downcast durch und rufen Sie checkDoors() auf
    • Verwenden Sie instanceof, um zu prüfen, ob es ein Motorcycle ist – wenn ja, führen Sie einen sicheren Downcast durch und rufen Sie checkSidecar() auf

Sie erhalten vier Eingaben: das Automodell (String), die Anzahl der Türen (int), das Motorradmodell (String) und ob es einen Beiwagen hat (boolean).

Ihre Ausgabe sollte vier Zeilen zeigen – für jedes Fahrzeug sehen Sie die Inspektionsmeldung, gefolgt von der typspezifischen Prüfung. Der instanceof-Operator stellt sicher, dass Sie Car-Methoden nur bei tatsächlichen Cars und Motorcycle-Methoden nur bei tatsächlichen Motorcycles aufrufen, was eine ClassCastException verhindert!

Spickzettel

Der instanceof-Operator prüft, ob ein Objekt eine Instanz einer bestimmten Klasse ist, bevor ein Casting durchgeführt wird:

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Sicherer Aufruf von Dog-spezifischen Methoden
}

Der Operator gibt true für die Klasse des Objekts und alle übergeordneten Klassen in der Hierarchie zurück:

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

Seit Java 16 kombiniert das Pattern Matching die Prüfung und das Casting in einem Schritt:

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' ist bereits gecastet und einsatzbereit
}

Der instanceof-Operator gibt false zurück, wenn er gegen null geprüft wird, wodurch separate Null-Prüfungen überflüssig werden.

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Eingaben lesen
        String carModel = scanner.nextLine();
        int numDoors = Integer.parseInt(scanner.nextLine());
        String motorcycleModel = scanner.nextLine();
        boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
        
        // TODO: Erstelle ein Car-Objekt mit carModel und numDoors
        
        // TODO: Erstelle ein Motorcycle-Objekt mit motorcycleModel und hasSidecar
        
        // TODO: Erstelle ein Array von Vehicle-Referenzen, das das Car und das Motorcycle enthält
        
        // TODO: Iteriere durch das Array und für jedes Fahrzeug:
        // 1. Rufe die Methode inspect() auf
        // 2. Verwende instanceof, um zu prüfen, ob es ein Car ist, führe dann einen Downcast durch und rufe checkDoors() auf
        // 3. Verwende instanceof, um zu prüfen, ob es ein Motorcycle ist, führe dann einen Downcast durch und rufe checkSidecar() auf
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung