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); // trueSeit 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.
Aufgabe
EinfachLassen 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 einmodel-Feld (String). Fügen Sie einen Konstruktor zur Initialisierung, eine Getter-MethodegetModel()und eine Methodeinspect()hinzu, die Folgendes ausgibt:"Inspecting vehicle: " + modelCar.java: Erstellen Sie eine Klasse, die Vehicle erweitert. Autos haben ein zusätzlichesnumDoors-Feld (int). Verwenden Siesuperfür die Initialisierung der Elternklasse. Fügen Sie eine MethodecheckDoors()hinzu, die Folgendes ausgibt:getModel() + " has " + numDoors + " doors"Motorcycle.java: Erstellen Sie eine weitere Klasse, die Vehicle erweitert. Motorräder haben einhasSidecar-Feld (boolean). Fügen Sie eine MethodecheckSidecar()hinzu, die je nach Boolean-Wert entwedergetModel() + " has a sidecar"odergetModel() + " has no sidecar"ausgibt.Main.java: Hier wirdinstanceofunverzichtbar! 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 SiecheckDoors()auf - Verwenden Sie
instanceof, um zu prüfen, ob es ein Motorcycle ist – wenn ja, führen Sie einen sicheren Downcast durch und rufen SiecheckSidecar()auf
- Rufen Sie die Basis-Methode
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); // trueSeit 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
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas this-SchlüsselwortMethodenFelder (Attribute)Konstruktor-MethodeKonstruktor-ÜberladungRückblick – Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (extends)Das super-SchlüsselwortMethoden überschreiben (@Override)Konstruktor-VerkettungDie Object-KlasseEinfache & mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenZusammenfassung - Mitarbeiter-Hierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-InterfaceZusammenfassung – Benutzerdefiniertes Sortieren2Zugriffsmodifikatoren & Kapselung
Überblick über ZugriffsebenenGetter- und Setter-MethodenInformation HidingDas final-SchlüsselwortRückblick – Bankkonto-Manager5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenZusammenfassung – Formenrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, geschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Sealed Classes (Java 17+)11Design Patterns Teil 1
Einführung in Design PatternsSingleton-PatternFactory-PatternBuilder-PatternObserver-PatternStrategy-Pattern14Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung3Klasseneigenschaften & Statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Zusammenfassung – Zähler & Utility6Interfaces & Abstrakte Klassen
Einführung in InterfacesInterfaces implementierenImplementierung mehrerer InterfacesDefault- & statische Methoden in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesZusammenfassung - Zahlungssystem