In Kotlin werden Generics (Generic-Parameter) standardmäßig gelöscht (type erasure): zur Laufzeit sind keine Informationen über die Typen verfügbar. Dies erschwert Reflexion, Typumwandlung und das Lesen von Annotations nach Typ. Für die meisten Aufgaben ist dies akzeptabel – normale Generics funktionieren ähnlich wie in Java.
Inline-Funktionen mit dem Parameter reified ermöglichen es, den Compiler "zwingen", einen bestimmten Typ an der Stelle des Aufrufs einzusetzen, wodurch die Funktion zur Laufzeit Operationen mit dem Typ durchführen kann (z. B. Typprüfungen, Erstellen neuer Instanzen mit Reflexion usw.). reified kann jedoch nur für Parameter in inline-Funktionen verwendet werden.
Beispielvergleich:
// Normaler Generic fun <T> printType(t: T) { println(t.javaClass) // Führt zu ClassCastException für List<Int> usw. } // mit reified inline fun <reified T> printType(t: T) { println(T::class.simpleName) } fun main() { printType(123) // Gibt aus: Int printType("hello") // Gibt aus: String }
Praktische Anwendung: Wird am häufigsten zur Typprüfung, Typumwandlung, Reflexion und Erstellen von Instanzen verwendet, wo der Typ anderweitig nicht erhalten werden kann.
"Kann eine Funktion mit reified-Typ nicht inline sein?"
reified funktioniert nur in Inline-Funktionen. Andernfalls ist die Typsubstition zur Kompilierungszeit unmöglich.Beispiel für falsche Verwendung:
fun <reified T> failFunction() {} // Kompilierungsfehler: reified type parameter can only be used on an inline function
Korrekt:
inline fun <reified T> goodFunction() {}
Geschichte
Im Projekt war es notwendig, universell JSON-Strings in jeden Typ über eine Funktion mit Generic-Parameter zu parsen. Die Standardimplementierung über
fun <T> parse(json: String): Tfunktionierte aufgrund der type erasure nicht korrekt – es war unmöglich, Class<T> für das Parsen von Sammlungen und generischen Modellen zu erhalten. Wir haben uns über inline mit reified Typ entschieden – das Problem verschwand.
Geschichte
Einer der Entwickler versuchte, Instanzen vom Typ T mit einem normalen Konstruktor
T()zu erstellen, ohne inline und reified zu verwenden. Zur Kompilierungszeit trat ein Fehler auf, da die Typinformationen gelöscht waren. Durch das Umschreiben auf inline fun <reified T: Any> konnten alle Probleme mit den Standardmittel der Sprache behoben werden.
Geschichte
Bei dem Versuch, reified in einer normalen Funktion (ohne inline) zu verwenden – gab IDE einen verwirrenden Kompilierungsfehler aus. Der Entwickler suchte lange nach der Ursache, bis er die Dokumentation studierte und die Funktion korrigierte, indem er inline hinzufügte.