Type Erasure und reifizierte Typparameter
Verwenden Sie reified mit inline-Funktionen, um zur Laufzeit auf Typinformationen zuzugreifen.
Type Erasure und reifizierte Typparameter ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.
Was ist Type Erasure?
Zur Laufzeit löscht die JVM generische Typargumente. List<String> und List<Int> sind beide einfach nur List. Dadurch sind Operationen auf generischen Typen zur Laufzeit eingeschränkt.
fun main() {
val strings: List<String> = listOf("a", "b")
val ints: List<Int> = listOf(1, 2)
println(strings.javaClass == ints.javaClass) // true: both ArrayList
println(strings is List<*>) // OK with star
// println(strings is List<String>) // warning: unchecked cast
}Das Problem: Gelöschte Typen können nicht geprüft werden
Sie können is nicht mit einem konkreten generischen Typargument verwenden, weil die Typinformationen zur Laufzeit nicht mehr vorhanden sind.
fun checkType(obj: Any) {
// This works:
if (obj is List<*>) println("It's a list of something")
// This doesn't compile cleanly:
// if (obj is List<String>) println("It's a list of strings") // unchecked
}
fun main() {
checkType(listOf("hello"))
checkType(42)
}Zusammenfassung zu inline-Funktionen
inline kopiert den Funktionskörper zur Kompilierzeit an die Aufrufstelle. Dadurch wird reified ermöglicht – auch das Typargument wird an der Aufrufstelle eingesetzt.
inline fun <T> myRun(block: () -> T): T = block()
fun main() {
val result = myRun { 42 }
println(result) // 42
// The compiler inlines the lambda body — no object allocation
}reified: Zugriff auf T zur Laufzeit
Die Kombination aus inline und reified bewahrt das Typargument an der Aufrufstelle und ermöglicht is, as und ::class für T.
inline fun <reified T> isInstance(value: Any): Boolean = value is T
fun main() {
println(isInstance<String>("hello")) // true
println(isInstance<Int>("hello")) // false
println(isInstance<List<*>>(listOf())) // true
}Die KClass von T abrufen
Mit reified T können Sie T::class zur Laufzeit abrufen – in generischen Funktionen normalerweise unmöglich.
inline fun <reified T> classNameOf(): String = T::class.simpleName ?: "Unknown"
fun main() {
println(classNameOf<String>()) // String
println(classNameOf<Int>()) // Int
println(classNameOf<List<*>>()) // List
}Sicherer Cast mit reified
Verwenden Sie reified, um eine typsichere Cast-Hilfsfunktion zu schreiben, die anstelle einer Ausnahme null zurückgibt.
inline fun <reified T> Any?.safeCast(): T? = this as? T
fun main() {
val obj: Any = "Hello"
val s: String? = obj.safeCast<String>()
val i: Int? = obj.safeCast<Int>()
println(s) // Hello
println(i) // null
}JSON-Parsing mit reified
Bibliotheken wie Gson oder kotlinx.serialization verwenden reified, um den Zieltyp an der Aufrufstelle abzuleiten, ohne explizit Class-Objekte zu übergeben.
import com.google.gson.Gson
// Simulated without real Gson:
inline fun <reified T> parseJson(json: String): T {
return Gson().fromJson(json, T::class.java)
}
// Usage:
// val user: User = parseJson<User>("""{"name":"Alice"}""")reified mit filterIsInstance
Die filterIsInstance<T>()-Funktion der Standardbibliothek verwendet reified, um eine Liste ohne manuelle Casts auf einen bestimmten Typ zu filtern.
fun main() {
val mixed: List<Any> = listOf(1, "hello", 2.5, "world", true)
val strings = mixed.filterIsInstance<String>()
val ints = mixed.filterIsInstance<Int>()
println(strings) // [hello, world]
println(ints) // [1]
}reified kann nicht in Nicht-inline-Funktionen verwendet werden
reified funktioniert nur mit inline-Funktionen. Die Verwendung ohne inline führt zu einem Kompilierfehler.
// Error:
// fun <reified T> broken(): String = T::class.simpleName ?: "?"
// Must be inline:
inline fun <reified T> correct(): String = T::class.simpleName ?: "?"
fun main() {
println(correct<Double>()) // Double
}reified und Reflection
Kombinieren Sie reified mit Reflection, um Properties oder Annotationen eines Typs dynamisch zu untersuchen, ohne standardmäßige Class-Parameter zu benötigen.
inline fun <reified T : Any> properties(): List<String> =
T::class.members.map { it.name }
data class Point(val x: Int, val y: Int)
fun main() {
println(properties<Point>()) // [x, y, component1, component2, copy, equals, hashCode, toString]
}Praktisch: Typsicherer Service Locator
Verwenden Sie reified, um einen Service Locator zu erstellen, der KClass auf Instanzen abbildet und so leichtgewichtige DI ohne Annotation-Prozessoren ermöglicht.
val registry = mutableMapOf<kotlin.reflect.KClass<*>, Any>()
inline fun <reified T : Any> register(instance: T) { registry[T::class] = instance }
@Suppress("UNCHECKED_CAST")
inline fun <reified T : Any> resolve(): T = registry[T::class] as T
class Logger { fun log(msg: String) = println("[LOG] $msg") }
fun main() {
register(Logger())
resolve<Logger>().log("Service located!")
}Einschränkungen von reified
reified-Typparameter können nicht in Nicht-inline-Kontexten verwendet, der Typ kann nicht für eine spätere Verwendung gespeichert und nicht an Nicht-inline-Funktionen übergeben werden, die den Typ zur Laufzeit benötigen.
inline fun <reified T> foo() {
val clazz = T::class // OK here
// bar(clazz) // must pass clazz explicitly to non-inline funs
println(clazz.simpleName)
}
fun bar(clazz: kotlin.reflect.KClass<*>) = println(clazz.simpleName)
fun main() { foo<String>() }Schnelltest
Was ist erforderlich, damit ein Typparameter reified sein kann?
Zusammenfassung
Type Erasure entfernt generische Typinformationen zur Laufzeit. reified bei inline-Funktionen bewahrt das Typargument an der Aufrufstelle und ermöglicht is, as, ::class und Reflection für T – ohne Class-Objekte manuell zu übergeben.
Häufig gestellte Fragen
Ist die Lektion „Type Erasure und reifizierte Typparameter“ kostenlos?
Ja — der vollständige Text von „Type Erasure und reifizierte Typparameter“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Type Erasure und reifizierte Typparameter“?
Verwenden Sie reified mit inline-Funktionen, um zur Laufzeit auf Typinformationen zuzugreifen. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Kotlin Academy zu starten?
Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „Type Erasure und reifizierte Typparameter“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?
Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Generische Funktionen und Typbeschränkungen mit where
- Varianz an der Deklarationsstelle: in und out
- Star Projection und wann * verwendet wird
- Type Erasure und reifizierte Typparameter