Top-Anfängerfehler von Kotlin-Entwicklern: von A bis Z

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum selbst kluge Entwickler an Kotlin scheitern

\n\n

Kotlin ist eine elegante und leistungsstarke Sprache, die die Herzen von Millionen Entwicklern erobert hat. Aber ihre Prägnanz und Flexibilität bergen Fallstricke, besonders für Anfänger, die von Java oder anderen Sprachen kommen. Viele denken, dass Kotlin „verständlicher“ als Java ist und es daher weniger Fehler geben wird. In der Praxis ist das Gegenteil der Fall: Das Unverständnis der Sprachphilosophie führt zu Bugs, die schwer zu finden sind.

\n\n

In diesem Artikel analysieren wir die Top-Anfängerfehler von Kotlin-Entwicklern – von der banalen Ignorierung von null safety bis zur falschen Verwendung von Coroutines. Jeder Fehler wird mit einem Codebeispiel und einem praktischen Tipp zur Vermeidung veranschaulicht.

\n\n

1. Null Safety: Wann „?“ rettet und wann nicht

\n\n

1.1. Ignorieren von nullable Typen

\n

Der häufigste Fehler ist die Verwendung von !! (not-null assertion), wo man mit sicheren Aufrufen auskommen könnte. Anfänger schreiben oft:

\n\n
fun printLength(str: String?) {\n    println(str!!.length) // Wirft NPE, wenn str == null\n}
\n\n

Der richtige Ansatz ist die Verwendung von ?.let oder des Elvis-Operators ?::

\n\n
fun printLength(str: String?) {\n    str?.let { println(it.length) } ?: println("String ist null")\n}
\n\n

1.2. Smart Cast vergessen

\n

Kotlin führt nach einer null-Prüfung automatische Typumwandlungen durch, aber Anfänger bemerken das nicht:

\n\n
fun process(value: Any?) {\n    if (value is String) {\n        // value ist bereits String, kein Cast nötig!\n        println(value.length) // Funktioniert ohne (value as String).length\n    }\n}
\n\n

Tipp: Vertrauen Sie dem Compiler. Verwenden Sie !! nur, wenn Sie zu 100% sicher sind, dass der Wert nicht null ist, und bereit sind, bei einem Fehler abzustürzen.

\n\n

2. Sealed Class und When: Fallstricke der Vollständigkeit

\n\n

2.1. Verwendung des else-Zweigs mit sealed class

\n

Sealed classes wurden entwickelt, damit der Compiler prüft, ob alle Varianten behandelt wurden. Aber Anfänger fügen oft else hinzu und zerstören damit die ganze Magie:

\n\n
sealed class Result {\n    data class Success(val data: String) : Result()\n    data class Error(val message: String) : Result()\n}\n\nfun handleResult(result: Result) {\n    when (result) {\n        is Result.Success -> println(result.data)\n        is Result.Error -> println(result.message)\n        else -> {} // Fehler! Wenn eine neue Unterklasse hinzugefügt wird, warnt der Compiler nicht\n    }\n}
\n\n

Richtig ist es, else nicht zu verwenden:

\n\n
fun handleResult(result: Result) {\n    when (result) {\n        is Result.Success -> println(result.data)\n        is Result.Error -> println(result.message)\n    } // Der Compiler gibt einen Fehler aus, wenn nicht alle Zweige abgedeckt sind\n}
\n\n

2.2. Verwechslung von sealed class und enum

\n

Anfänger wählen oft enum, wo ein sealed class benötigt wird. Denken Sie daran: enum ist für eine endliche Menge von Konstanten, sealed class für eine Hierarchie mit unterschiedlichen Daten in jeder Unterklasse.

\n\n

3. Scope Functions: apply, let, run, with, also – wie man nicht durcheinanderkommt

\n\n

3.1. Vermischung des Kontexts: this vs it

\n

Die häufigste Verwirrung entsteht, wenn ein Anfänger apply (Kontext – this) für Operationen verwendet, die let (Kontext – it) erfordern:

\n\n
data class User(var name: String, var age: Int)\n\nfun initUser(): User {\n    return User("Anonym", 0).apply {\n        // this ist User\n        name = "Ivan"\n        age = 25\n    }\n}\n\nfun printUserInfo(user: User?) {\n    user?.let { \n        // it ist user\n        println("Name: ${it.name}, Alter: ${it.age}")\n    }\n}
\n\n

3.2. Sinnlose Ketten von scope functions

\n

Anfänger lieben es, Ketten wie diese zu schreiben:

\n\n
list?.let { it.filter { it > 5 }.also { println(it) } }

                
                

Blogs

Buchempfehlungen