Historie der Frage:
Das Schlüsselwort instanceof wurde in Java eingeführt, um zu überprüfen, ob ein Objekt zu einem bestimmten Typ oder dessen Untertyp gehört. Der Mechanismus ermöglicht es, den Typ des Objekts zur Laufzeit zu präzisieren, was für die Arbeit mit generischen Sammlungen, Polymorphismus und Typumwandlung wichtig ist.
Problem:
Ohne korrekte Typbestimmung sind ClassCastException-Fehler oder falsche Logikbehandlungen in den Codezweigen möglich, wenn Typumwandlungen ohne Überprüfung durchgeführt werden. Übermäßige Verwendung von instanceof ist oft ein Zeichen für misslungenes Design.
Lösung:
instanceof gibt true zurück, wenn das Objekt eine Instanz der angegebenen Klasse oder einer ihrer Unterklassen ist oder ein Interface implementiert. In Java 16 wurde ein Mustermatching mit automatischer Typumwandlung im if-Block eingeführt.
Beispielcode:
Object obj = "Hello!"; if (obj instanceof String) { String s = (String) obj; // Die Umwandlung ist sicher System.out.println(s.length()); }
Ab Java 16:
if (obj instanceof String s) { System.out.println(s.length()); // s wird automatisch zu String umgewandelt }
Hauptmerkmale:
null instanceof Type ist immer false)Was gibt null instanceof SomeClass zurück?
Immer false. Der Operator garantiert, dass wenn das Objekt null ist, das Ergebnis — false ist, was NullPointerException ausschließt.
Kann instanceof mit Generik-Parametern verwendet werden, z.B. if (obj instanceof List<String>)?
Nein. Aufgrund der Typauslöschung (type erasure) ist es nicht möglich, generische Parameter zur Laufzeit zu überprüfen. Die Überprüfung erfolgt immer nur nach dem Raw-Typ (z.B. List).
Beispielcode:
List<String> list = ...; if (list instanceof List<String>) { ... } // Kompilierungsfehler if (list instanceof List) { ... } // Erlaubt
Kann die Verwendung von instanceof auf Designprobleme im Code hinweisen?
Ja. Ständige Verwendung von instanceof anstelle von Abstraktionen oder Mustern (z.B. das Visitor-Muster) zeigt oft eine Verletzung der OOP-Prinzipien, wie Öffnung/Schließung, an.
In der Methode gibt es eine große Kette von if-else-Anweisungen zur Überprüfung aller möglichen Unterklassen einer Superklasse über instanceof, innerhalb jedes Zweigs erfolgt die Typumwandlung und der Aufruf der entsprechenden Methode.
Vorteile:
Nachteile:
Anstelle von if-else wurde das Visitor-Muster implementiert: Jede Unterklasse hat eine Methode, die das benötigte Verhalten aufruft, was die Verwendung von instanceof vermeidet.
Vorteile:
Nachteile: