«instanceof» in Kotlin: Warum es nicht Java ist und wie es den Code sauberer macht
\n\nWenn Sie aus der Java-Welt zu Kotlin gekommen sind, sind Sie wahrscheinlich an das Schlüsselwort instanceof gewöhnt. Es hilft herauszufinden, ob ein Objekt eine Instanz einer bestimmten Klasse ist. Aber in Kotlin gibt es diesen Operator nicht. Und das ist kein Fehler, sondern ein Feature.
Kotlin bietet eine viel elegantere, sicherere und prägnantere Möglichkeit, den Typ eines Objekts zu überprüfen – den Operator is. Er beantwortet nicht nur die Frage „Wer bist du?“, sondern führt das Objekt auch automatisch in den erforderlichen Typ über. Dies nennt man Smart Cast, und es ist eine dieser Funktionen, die das Programmieren in Kotlin so angenehm machen.
In diesem Leitfaden behandeln wir:
\n- \n
- Wie man den Operator
isanstelle voninstanceofverwendet; \n - Was ein Smart Cast ist und wie er funktioniert; \n
- Wie man mehrere Typen elegant mit
whenbehandelt; \n - Worin sich der sichere Cast
as?vom normalenasunterscheidet; \n - Und natürlich reale Codebeispiele. \n
Los geht's!
\n\n1. Der Operator is – das direkte Analogon zu instanceof
\n\nIn Java würden Sie schreiben:
\nif (obj instanceof String) {\n String str = (String) obj;\n System.out.println(str.length());\n}\n\nIn Kotlin sieht dasselbe so aus:
\nif (obj is String) {\n println(obj.length) // Smart Cast! obj ist bereits ein String\n}\n\nBeachten Sie: Nach der Prüfung obj is String müssen Sie nicht explizit obj in den Typ String umwandeln. Der Kotlin-Compiler weiß selbst, dass die Variable obj innerhalb des if-Blocks garantiert ein String ist. Das ist ein Smart Cast.
Wie funktioniert das unter der Haube?
\nDer Compiler analysiert den Ausführungsfluss. Wenn er eine is-Prüfung sieht und keine Möglichkeit findet, den Typ der Variable zwischen Prüfung und Verwendung zu ändern (z. B. in Multithread-Code oder bei Änderung von var), führt er automatisch den Cast durch. Für val funktioniert das immer, für var nur, wenn die Variable zwischen Prüfung und Verwendung nicht geändert werden kann.
2. Negation: !is
\n\nMöchten Sie prüfen, dass ein Objekt nicht zu einem Typ gehört? Verwenden Sie !is:
if (obj !is String) {\n println("Das ist kein String")\n} else {\n // Hier ist obj automatisch ein String geworden\n println("Länge des Strings: ${obj.length}")\n}\n\nPraktisch und lesbar, oder?
\n\n3. Mehrfachprüfungen mit when
\n\nStellen Sie sich nun vor, Sie haben ein Objekt, das einer von mehreren Typen sein kann. In Java würden Sie eine Kette von if-else if mit instanceof schreiben. In Kotlin gibt es ein eleganteres Werkzeug – die when-Konstruktion.
fun describe(obj: Any): String {\n return when (obj) {\n is String -> "String mit Länge ${obj.length}"\n is Int -> "Ganze Zahl: $obj"\n is List<*> -> "Liste mit ${obj.size} Elementen"\n is Map<*, *> -> "Map mit ${obj.size} Einträgen"\n else -> "Unbekannter Typ"\n }\n}\n\nfun main() {\n println(describe("Hallo")) // String mit Länge 5\n println(describe(42)) // Ganze Zahl: 42\n println(describe(listOf(1,2)))// Liste mit 2 Elementen\n}\n\nBeachten Sie: Innerhalb jedes when-Zweigs funktioniert der Smart Cast ebenfalls! Im Zweig is String wird die Variable obj bereits als String betrachtet, und Sie können obj.length ohne zusätzlichen Cast aufrufen.
Das ist viel kompakter und sicherer als ein klassisches switch oder eine if-Kette.
4. Sicherer Cast: as?
\n\nManchmal müssen Sie nicht nur den Typ prüfen, sondern sofort einen Wert eines bestimmten Typs erhalten. In Java würden Sie (String) obj