In Kotlin wurde das Konzept der Inline-/Value-Klassen (jetzt Value-Klasse genannt) eingeführt, um den Runtime-Overhead bei der Arbeit mit Wrappers für Primitive und kleinen Strukturen zu minimieren. Die Idee stammt aus anderen Sprachen (zum Beispiel C#-Strukturen), wo eine solche Optimierung nützlich ist, um die Leistung zu steigern, ohne die Typisierung zu verlieren.
Die Erstellung von Wrapper-Klassen (zum Beispiel für Entity-Typen oder Identifikatoren) ohne Optimierung führt zur Schaffung eines zusätzlichen Objekts im Speicher, was die Leistung, GC beeinflusst und zu Boxing/Unboxing-Overhead führen kann. Oft besteht der Wunsch, eine strenge Typisierung (zum Beispiel UserId anstelle von Int) zu haben, aber ohne tatsächlich Objekte zu erstellen.
Die Value-Klasse wird mit dem Modifikator value deklariert. In den meisten Situationen erstellt die JVM kein zusätzliches Objekt — die Value-Klasse wird direkt durch ihr Feld ersetzt (Inlining). Dies bietet Typensicherheit und Leistung, die der von „einfachen Int“ nahekommt.
Beispielcode:
@JvmInline value class UserId(val value: Int) fun showId(id: UserId) = println(id.value) val id = UserId(15) showId(id) // Ohne Erstellung eines separaten Objekts UserId
Wichtige Merkmale:
Können Value-Klassen mehrere Eigenschaften haben?
Nein, Value-Klassen können nur eine Eigenschaft enthalten.
// Fehler: // value class Money(val amount: Int, val currency: String)
Kann eine Value-Klasse mit nullable-Eigenschaft erstellt werden?
Das Value-Feld einer Value-Klasse kann nicht nullable sein – nur nicht-nullable Typen.
// Fehler: // value class Name(val value: String?)
Kann Vererbung mit Value-Klassen verwendet werden?
Value-Klassen unterstützen keine Vererbung und können nicht abstrakt oder sealed sein.
// Fehler: // value class NewId(val value: Int): BaseId()
Ein Entwickler hat eine Value-Klasse für eine Entität mit zwei Eigenschaften (zum Beispiel ein Paar Int und String) erstellt und erhielt einen Kompilierungsfehler.
Vorteile:
Ein Entwickler verwendet eine Value-Klasse für einen Identifikator-Typ mit einem Feld (zum Beispiel UserId), was schnell und sicher funktioniert.
Vorteile: