Ceci pourrait être une question stupide, mais je viens de voir une question demandant Comment créer une variable de type pour un type générique . Le consensus semblait être que vous devriez avoir une méthode factice qui renvoie ce type, puis utilisez la réflexion pour l'obtenir (dans ce cas, il souhaitait mappe Type mapStringString = new ParameterizedType() {
public Type getRawType() {
return Map.class;
}
public Type getOwnerType() {
return null;
}
public Type[] getActualTypeArguments() {
return new Type[] { String.class, String.class };
}
};
4 Réponses :
Bien sûr, et pour la plupart des applications, cela serait probablement suffisant. P>
Cependant, en utilisant la première méthode, vous obtenez un objet plus raffiné. Disons par exemple que vous créez un objet Même raisonnement s'applique à d'autres (méthodes parfois utiles) telles que type1 code> à l'aide de la première méthode et type2 code> à l'aide de la deuxième méthode. Alors type1.equals (type2) code> retournerait true (puisque la première méthode renvoie un objet qui implémente correctement la méthode EQUALS) mais type2.equals (type1) code> retournerait faux (Depuis dans la deuxième méthode, vous n'avez pas remplacé la méthode des égaux et utilisez la mise en œuvre à partir de objet code>). P>
Tostring code>, hashcode code> etc. La deuxième méthode ne fournit pas de mise en œuvre utile de ceux-ci. P>
En fait, Type1 (Sun.Reflect.Generics.ReflectiveObjectS.ParameDeDtypeMPEIMP L) La mise en œuvre d'équivalements semble lancer le paramètre d'équivalent à des éléments paramétionnés, puis utilisez les méthodes d'interface pour comparer les classes, donc type1.equals (type2) code> retournerait vrai, bien que l'inverse ( type2.equals (type1) code>) reviendrait faux; Vous pouvez également mettre en œuvre ceux-ci aussi, mais le code devient alors un peu chunky
Sûr. Vous pouvez obtenir le même résultat dans la méthode 2 comme dans la méthode 1, mais cela nécessite d'autres travaux, comme vous l'avez remarqué.
En fait, je pense que le moyen le plus simple (== moins de code) est une interface factice qui étend le type de votre intéressé, puis GetGenericinterfaces () [0] code> de sa classe (Utiliser GetGenericClass () si vous êtes intéressé par une classe): private interface MapStringString extends Map<String, String> {}
private static ParameterizedType mapStringString(){
return (ParameterizedType) MapStringString.class.getGenericInterfaces()[0];
}
Bien que cela semble "hacjou" comme la première méthode que j'ai donnée, cela donne au moins un meilleur code de recherche où vous essayez d'obtenir le type (appeler simplement la fonction au lieu de faire la classe, puis obtenir une méthode de retour générique à chaque fois vous voulez l'utiliser).
Si vous incluez Google bibliothèque GUAVA dans votre projet (vous devriez; c'est génial ), utilisez son < Code> Typeoken code> pour obtenir un type. bibliothèque GSON (pour interagir avec JSON) a un version . Les deux sont utilisés comme celui-ci (pour obtenir un type si vous ne voulez pas compter sur Toutes les bibliothèques tierces, vous pouvez toujours utiliser des types anonymes pour obtenir un type générique concret em> avec une ligne de code (cette technique ne fonctionnera pas avec des interfaces et pourrait être plus de problèmes que cela ne vaut pour les types abstraits) . Pour obtenir un type J'ai vérifié que résultant type code> représentant Liste type code> représentant hashmap Type Code> Instance .Qquals () Code> Type Code> Les instances créées par GSON 'S typé (code> , mais n'a pas vérifié la même chose pour la version de GUAVA de Typeoken code> , que je n'ai pas accès à pour le moment. (Guava est une bibliothèque plus générale qui est si pratique pour toutes sortes de choses, vous devriez probablement l'utiliser de toute façon.) P> p>
Cela nécessite toujours que la liste
En plus des libs mentionnés de Google, il existe également une lib de Apache qui fait le travail.
import org.apache.commons.lang3.reflect.TypeUtils; ... ParameterizedType type = TypeUtils.parameterize(List.class, Double.class); ...
J'essaie de faire ce que votre solution proposée permet: Obtenez un type paramétré à partir d'un type brut et de la liste des paramètres de type fournis à l'heure de la compilation. Avez-vous trouvé une autre façon de faire cela?