value class in Kotlin – typsichere IDs ohne Extra-Kosten zur Laufzeit
Ein `String` für die Nutzer-ID, ein `String` für die Bestell-ID – und schon vertauschst du sie irgendwann. Mit `@JvmInline value class` bekommst du echte, unverwechselbare Typen, die zur Laufzeit trotzdem nur der nackte Wert sind. Kein Wrapper-Objekt, keine Bremse.
Kennst du das? Eine Funktion nimmt userId: String und orderId: String. Beide sind String, der Compiler nickt alles ab – und irgendwann übergibst du sie in der falschen Reihenfolge. Der Fehler fällt erst zur Laufzeit auf, im schlimmsten Fall bei echten Nutzern. Kotlins value class löst genau das: Du machst aus einem simplen Wert einen eigenen Typ, den man nicht mehr verwechseln kann – und zahlst dafür zur Laufzeit nichts.
Das Problem: alles ist ein String
fun ladeBestellung(userId: String, orderId: String) { /* ... */ }
val user = "u_42"
val order = "o_7"
ladeBestellung(order, user) // vertauscht – der Compiler merkt NICHTSDie Lösung: value class
@JvmInline value class UserId(val raw: String)
@JvmInline value class OrderId(val raw: String)
fun ladeBestellung(userId: UserId, orderId: OrderId) { /* ... */ }
ladeBestellung(OrderId("o_7"), UserId("u_42"))
// Fehler beim KOMPILIEREN: Type mismatch – nicht erst zur LaufzeitUserId und OrderId sind jetzt verschiedene Typen. Die Reihenfolge zu vertauschen, wird zum Compiler-Fehler statt zum Support-Ticket. Das Schöne: Ein value class mit einer einzigen Property wird vom Compiler, wo immer möglich, wieder auf den nackten Wert eingedampft (hier also auf den String). Es entsteht kein zusätzliches Objekt auf dem Heap – anders als bei einer normalen data class. Du bekommst also Sicherheit geschenkt, ohne Speicher oder Tempo zu opfern.
Auch für Werte mit Einheit – und mit eigener Logik
Der Trick trägt weiter als IDs. Überall, wo eine nackte Zahl eine Bedeutung hat, verhindert ein eigener Typ Einheiten-Verwechslungen. Ein value class darf auch Methoden und berechnete Properties haben:
@JvmInline value class Cents(val value: Long) {
val euros: Double get() = value / 100.0
operator fun plus(other: Cents) = Cents(value + other.value)
override fun toString() = "%.2f €".format(euros)
}
val preis = Cents(1990) + Cents(500)
println(preis) // 24,95 €Damit kann dir niemand mehr aus Versehen Euro und Cent addieren.
Zwei Dinge, die du wissen solltest
- Sobald der Typ „verpackt" gebraucht wird, entsteht doch ein Objekt. Steckst du einen
Cents-Wert in eineList<Cents>, machst ihnnullable(Cents?) oder gibst ihn als generischen Typ weiter, muss Kotlin ihn boxen. Für den heißen Pfad ist das gut zu wissen; im Normalfall ist es egal. init-Block für Validierung nutzen. So sind ungültige Werte gar nicht erst baubar:
@JvmInline value class Email(val raw: String) {
init { require("@" in raw) { "Keine gültige E-Mail: $raw" } }
}Ich nutze value class in fast jedem Android-Projekt für IDs und Geldbeträge – das räumt eine ganze Klasse dummer Fehler ab, bevor sie überhaupt entstehen. Wenn du eine saubere, wartbare App in Kotlin und Jetpack Compose brauchst, schreib mir über bymw.de.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
Enum-Klassen in Kotlin – mit Eigenschaften und Methoden
Enums sind mehr als eine Liste von Konstanten. In Kotlin bekommt jeder Wert eigene Eigenschaften und Methoden – perfekt für Zustände, Kategorien oder Konfiguration.
animateAsState in Jetpack Compose – flüssige Animationen in einer Zeile
Du willst, dass sich Größe, Farbe oder Position weich verändern, statt hart umzuspringen? In Compose brauchst du dafür keinen Animator und keinen State-Maschinen-Zoo – ein animateDpAsState oder animateColorAsState reicht. Ich zeige dir, wie das funktioniert.
when in Kotlin – mehr als ein switch
when ersetzt das switch aus Java, kann aber viel mehr: es liefert einen Wert zurück, prüft Bereiche und Mengen, arbeitet ohne Argument wie eine if-Kette und erzwingt bei sealed-Typen Vollständigkeit. Ich zeige dir alle vier Varianten.