Einleitung: Warum will die Data Class nicht leer sein?
\n\nHaben Sie jemals versucht, eine data class in Kotlin für Android zu erstellen und mit Überraschung festgestellt, dass der Compiler sich weigert, einen leeren Konstruktor zu akzeptieren? Wenn ja – Sie sind nicht allein. Diese Frage hat tausende Aufrufe auf Stack Overflow gesammelt, was bedeutet, dass hunderte Entwickler (vom Anfänger bis zum Erfahrenen) über denselben Stolperstein gestolpert sind.
Warum passiert das? Der Grund ist, dass eine data class in Kotlin nicht einfach eine Klasse zum Speichern von Daten ist. Sie generiert automatisch die Funktionen equals(), hashCode(), toString(), copy() und componentN(). Und für all diese Magie benötigt sie einen primary constructor mit mindestens einem Parameter. Ohne diesen geht es nicht.
In diesem Artikel analysieren wir die Top-5-Fehler, die Entwickler beim Versuch machen, einen leeren Konstruktor für eine data class in Kotlin Android zu erstellen, und zeigen, wie man sie vermeidet. Los geht's!
Fehler Nr. 1: Direkte Deklaration eines leeren Konstruktors
\n\nDer häufigste Fehler ist der Versuch, so etwas zu schreiben:
\n\n// ❌ So geht das nicht!\ndata class User {\n constructor() : this() // Kompilierungsfehler\n}\n\n\nKotlin verlangt strikt, dass der primary constructor im Klassenkopf deklariert wird. Wenn Sie versuchen, einen sekundären Konstruktor ohne Parameter zu erstellen, der sich selbst aufruft, erhalten Sie eine Endlosschleife und einen Kompilierungsfehler.
\n\nLösung: Standardwerte
\n\nDer einfachste und eleganteste Weg ist, Standardwerte für alle Parameter des primary constructor festzulegen:
\n\n// ✅ Richtig: Standardwerte\ndata class User(\n val name: String = "",\n val age: Int = 0,\n val email: String = ""\n)\n\n// Jetzt kann ein Objekt ohne Argumente erstellt werden\nval emptyUser = User()\nprintln(emptyUser) // User(name=, age=0, email=)\n\n\nDieser Ansatz funktioniert "out of the box" und erfordert keine zusätzlichen Plugins oder Annotationen. Sie erhalten einen vollwertigen leeren Konstruktor, und alle Felder werden mit Standardwerten initialisiert.
\n\nFehler Nr. 2: Ignorieren der Anforderungen von Bibliotheken (Room, Retrofit, Gson)
\n\nViele Bibliotheken für Android erfordern einen leeren Konstruktor, um Objekte über Reflection zu erstellen. Ein klassisches Beispiel ist Room:
\n\n// ❌ Room wird einen Fehler ausgeben\n@Entity\ndata class User(\n @PrimaryKey val id: Int,\n val name: String,\n val age: Int\n)\n\n\nBeim Versuch, eine solche data class mit Room zu verwenden, erhalten Sie eine Ausnahme: Cannot instantiate User using no-arg constructor. Ähnliche Probleme treten bei Gson und Retrofit bei der Deserialisierung von JSON auf.
Lösung: Standardwerte + nullable Typen
\n\nFür Room reicht es, Standardwerte hinzuzufügen:
\n\n// ✅ Room ist zufrieden\n@Entity\ndata class User(\n @PrimaryKey val id: Int = 0,\n val name: String = "",\n val age: Int = 0\n)\n\n\nFür Gson und Retrofit ist es oft einfacher, nullable Typen zu verwenden:
\n\n// ✅ Für die Arbeit mit JSON\ndata class ApiResponse(\n val status: String? = null,\n val data: List<Item>? = null\n)\n\n\nSeien Sie jedoch vorsichtig: nullable Typen können zu NPE führen, wenn Sie vergessen, den Wert zu überprüfen. Verwenden Sie sie bewusst.
\n\nFehler Nr. 3: Vergessenes Kotlin No-Arg Plugin
\n\nManchmal sind Standardwerte nicht geeignet. Zum Beispiel, wenn Sie Jackson zur Serialisierung verwenden und bestimmte Typen ohne nullable benötigen. In diesem Fall hilft das Plugin kotlin-noarg.
Viele Entwickler denken fälschlicherweise, dass es ausreicht, einfach eine Abhängigkeit in build.gradle hinzuzufügen. Aber ohne korrekte Konfiguration funktioniert das Plugin nicht.
Lösung: Korrekte Konfiguration von No-Arg
\n\nFügen Sie das Plugin in build.gradle.kt hinzu