2010-06-07 3 views
4

En Java, comment puis-je construire un objet Type pour Map<String, String>?Création d'un objet Type correspondant à un type générique

System.out.println(Map<String, String>.class); 

ne compile pas. Une solution de contournement que je peux penser est

Map<String, String> dummy() { throw new Error(); } 
Type mapStringString = Class.forName("ThisClass").getMethod("dummy", null).getGenericReturnType(); 

Est-ce la bonne façon?

+0

vous devez faire du public pour que le hack fonctionne. – aioobe

+0

Pour quoi avez-vous besoin de cette information, après tout? Si vous développez cela, de meilleures réponses peuvent être données. – BalusC

+1

@aioobe Si c'est la même classe, alors 'private' est correct. 'ThisClass.class' ou' getClass() 'aurait été préférable à l'utilisation de' Class.forName'. –

Répondre

4
public class Test { 
    public Map<String, String> dummy; 
    public static void main(String... args) throws SecurityException, 
                NoSuchFieldException { 
     Type mapStringString = Test.class.getField("dummy").getGenericType(); 
     // ... 

Est-ce un légèrement bidouille moins laid ..


Comme Tom Hawtin suggère, vous pouvez mettre en œuvre les méthodes vous:

Type mapStrStr2 = new ParameterizedType() { 
    public Type getRawType() { 
     return Map.class; 
    } 
    public Type getOwnerType() { 
     return null; 
    } 
    public Type[] getActualTypeArguments() { 
     return new Type[] { String.class, String.class }; 
    } 
}; 

renvoie les mêmes valeurs que l'autre approche pour les méthodes déclarées au ParameterizedType. Le résultat de la première approche même .equals ce type. (Cependant, cette approche ne remplace pas toString, equals et ainsi de suite, donc en fonction de vos besoins, la première approche pourrait être meilleure.)

+0

déclarant statique factice finale serait encore moins laid :) – codymanix

0

Oui c'est la bonne et la seule façon d'obtenir les génériques lors de l'exécution. Le type est effacé ("type erasure"), le Bytecode-Map est actuellement une carte Object-to-Object, la définition des génériques dans le code source est seulement utilisée par le compilateur pour assurer la sécurité du type.

+0

L'affiche originale demande 'Type' pas 'Class'. –

+0

Tout ce qui concerne 'Map .class' est connu au moment de la compilation, il n'y a donc aucune raison de ne pas compiler. –

+0

@Alexey Le problème est que 'Map .class' n'a absolument aucun sens. –

2

Tout est fait avec des interfaces, donc vous pouvez construire votre propre implémentation. Cependant, le moyen le plus simple est d'utiliser la réflexion sur une classe fictive créée à cet effet.

Questions connexes