J'essaie de comprendre le but du reified
mot - clé, apparemment cela nous permet de faire une réflexion sur les génériques .
Cependant, quand je le laisse de côté, cela fonctionne tout aussi bien. Quelqu'un veut-il expliquer quand cela fait une réelle différence ?
Réponses:
TL; DR: Ce qui est
reified
bon pourDans le corps d'une fonction générique comme
myGenericFun
, vous ne pouvez pas accéder au typeT
car il est uniquement disponible au moment de la compilation mais effacé au moment de l'exécution. Par conséquent, si vous souhaitez utiliser le type générique en tant que classe normale dans le corps de la fonction, vous devez transmettre explicitement la classe en tant que paramètre, comme indiqué dansmyGenericFun
.Si vous créez une
inline
fonction avec un reifiedT
, le type deT
peut être consulté même au moment de l'exécution et vous n'avez donc pas besoin de passer leClass<T>
. Vous pouvez travailler avecT
comme si elle était une classe normale, par exemple , vous pouvez vérifier si une variable est une instance deT
, que vous pouvez facilement faire alors:myVar is T
.Une telle
inline
fonction avecreified
typeT
ressemble à ceci:Comment
reified
fonctionneVous ne pouvez utiliser
reified
qu'en combinaison avec uneinline
fonction . Une telle fonction oblige le compilateur à copier le bytecode de la fonction à chaque endroit où la fonction est utilisée (la fonction est "en ligne"). Lorsque vous appelez une fonction en ligne avec un type réifié, le compilateur connaît le type réel utilisé comme argument de type et modifie le bytecode généré pour utiliser directement la classe correspondante. Par conséquent, les appels commemyVar is T
deviennentmyVar is String
(si l'argument type l'étaitString
) dans le bytecode et à l'exécution.Exemple
Jetons un coup d'œil à un exemple qui montre à quel point cela
reified
peut être utile . Nous voulons créer une fonction d'extension pourString
calledtoKotlinObject
qui tente de convertir une chaîne JSON en un objet Kotlin simple avec un type spécifié par le type générique de la fonctionT
. Nous pouvons utilisercom.fasterxml.jackson.module.kotlin
pour cela et la première approche est la suivante:a) Première approche sans type réifié
La
readValue
méthode prend un type qu'elle est censée analyser leJsonObject
to. Si nous essayons d'obtenir leClass
paramètre de typeT
, le compilateur se plaint: "Impossible d'utiliser 'T' comme paramètre de type réifié. Utilisez une classe à la place."b) Solution de contournement avec un
Class
paramètre explicitePour contourner le problème, vous pouvez faire de
Class
ofT
un paramètre de méthode, qui sera ensuite utilisé comme argument dereadValue
. Cela fonctionne et est un modèle courant dans le code Java générique. Il peut être appelé comme suit:c) La voie Kotlin:
reified
L'utilisation d'une
inline
fonction avecreified
paramètre de typeT
permet d'implémenter la fonction différemment:Il n'est pas nécessaire de prendre le
Class
de enT
plus,T
peut être utilisé comme s'il s'agissait d'une classe ordinaire. Pour le client, le code ressemble à ceci:Remarque importante: utilisation de Java
Une fonction inline avec
reified
type ne peut pas être appelée à partir du code Java .la source
FACILE
* réifié est de donner la permission d'utiliser au moment de la compilation (pour accéder à T à l'intérieur de la fonction)
par exemple:
en utilisant comme:
la source