Ich versuche den Sinn des reified
Keywords zu verstehen, anscheinend es erlaubt uns, darüber nachzudenken Generika .
Aber wenn ich es weglasse, funktioniert es genauso gut. Will jemand erklären, wenn dies einen tatsächlichen Unterschied macht?
reified
gut für In einer normalen generischen Funktion wie
%Vor% Sie können nicht auf den Typ T
zugreifen, da nur zur Kompilierzeit verfügbar ist , aber gelöscht zur Laufzeit. Wenn Sie also den generischen Typ als normale Klasse im Funktionskörper verwenden möchten, müssen Sie explizit die Klasse als Parameter übergeben , wie in myGenericFun
gezeigt.
Wenn Sie eine inline
-Funktion mit einem verdinglicht T
erstellen, können Sie auch auf den Typ von T
zugreifen, auch zur Laufzeit, so dass Sie Class<T>
nicht übergeben müssen. zusätzlich. Sie können mit T
so arbeiten, als wäre es eine normale Klasse, z. Vielleicht möchten Sie überprüfen, ob eine Variable eine Instanz von T
ist, was Sie dann einfach tun können: myVar is T
.
Eine solche Funktion inline
mit reified
type T
sieht folgendermaßen aus:
reified
Sie können reified
nur in Kombination mit einer Funktion inline
verwenden. Eine solche Funktion bewirkt, dass der Compiler den Bytecode der Funktion an jede Stelle kopiert, an der die Funktion verwendet wird (die Funktion wird "inline").
Wenn Sie eine Inline-Funktion mit einem verdichteten Typ aufrufen, kennt der -Compiler den eigentlichen Typ, der als Typargument verwendet wird, und ändert den generierten Bytecode, um die entsprechende Klasse direkt zu verwenden.
Daher werden Aufrufe wie myVar is T
zu myVar is String
(wenn das Typargument String
war) im Bytecode und zur Laufzeit.
Sehen wir uns ein Beispiel an, das zeigt, wie hilfreich reified
sein kann.
Wir möchten eine Erweiterungsfunktion für String
namens toKotlinObject
erstellen, die versucht, eine JSON-Zeichenfolge in ein einfaches Kotlin-Objekt mit einem Typ zu konvertieren, der vom generischen Typ der Funktion T
angegeben wird. Wir können com.fasterxml.jackson.module.kotlin
dafür verwenden und der erste Ansatz ist folgender:
Erste Annäherung ohne verdichteten Typ
%Vor% Die Methode readValue
verwendet einen Typ, mit dem JsonObject
analysiert werden soll. Wenn wir versuchen, die Class
des Typparameters T
zu erhalten, beschwert sich der Compiler: "Kann 'T' nicht als verdingter Typparameter verwenden. Stattdessen eine Klasse verwenden."
Umgehung mit explizitem Class
-Parameter
Als Workaround kann der Class
von T
zu einem Methodenparameter gemacht werden, der dann als Argument für readValue
verwendet wird. Dies funktioniert und ist ein allgemeines Muster im generischen Java-Code. Es kann wie folgt aufgerufen werden:
Der Kotlin-Weg: reified
Die Verwendung einer Funktion inline
mit reified
type Parameter T
ermöglicht es, die Funktion anders zu implementieren:
Es ist nicht nötig, das Class
von T
zusätzlich zu verwenden, T
kann verwendet werden, als wäre es eine gewöhnliche Klasse. Für den Client sieht der Code so aus:
Eine Inline-Funktion mit reified
type ist nicht aus Java -Code aufrufbar.
Tags und Links generics kotlin kotlin-reified-type-parameters