72 votes

Comment créer des expressions de type classe <List<?> >

Prendre le suivant:

public Class<List<String>> getObjectType() {
    // what can I return here?
}

Quelle classe expression littérale puis-je de retour de cette méthode qui permettra de satisfaire les médicaments génériques et de compiler? List.class ne compile pas, ni List.<String>class.

Si vous vous demandez "pourquoi", je suis en train d'écrire une implémentation de Printemps de l' FactoryBean<List<String>>, ce qui m'oblige à mettre en oeuvre Class<List<String>> getObjectType(). Cependant, ce n'est pas un Ressort question.

edit: Ma plaintive cris ont été entendus par les pouvoirs en place à SpringSource, et ainsi de Printemps 3.0.1 aura le type de retour d' getObjectType() changé d' Class<?>, qui justement évite le problème.

62voto

Bozho Points 273663

Vous pouvez toujours choisir ce dont vous avez besoin, comme

 return (Class<List<String>>) new ArrayList<String>().getClass();
 

ou

 return (Class<List<String>>) Collections.<String>emptyList().getClass();
 

Mais je suppose que ce n'est pas ce que vous recherchez. Eh bien, cela fonctionne, avec un avertissement, mais ce n'est pas vraiment "beau".

Je viens de trouver ça

Pourquoi n'y a-t-il pas de littéral de classe pour les types paramétrés génériques?

Parce qu'un type paramétré générique n'a pas de représentation exacte du type à l'exécution.

Donc, le casting pourrait être la seule voie à suivre.

17voto

Kevin Bourrillion Points 19677

Vous ne devez jamais utiliser la construction Class<List<String>>. Il est absurde, et devrait produire un avertissement en Java (mais qui ne marche pas). Des instances de classe représentent toujours cru types, de sorte que vous pouvez avoir Class<List>; c'est tout. Si vous voulez quelque chose pour représenter un réifiée de type générique, comme List<String>, vous avez besoin d'un "super-type de jeton" comme Guice utilise:

http://google-guice.googlecode.com/git/javadoc/com/google/inject/TypeLiteral.html

9voto

finnw Points 24592

L'existence d'un Class<List<String>> est intrinsèquement dangereuse. Voici pourquoi:

 // This statement generates a warning - for a reason...
Class<List<String>> unsafeListClass = (Class<List<String>>) (Class<?>) List.class;

List<Integer> integerList = new ArrayList<Integer>(); // Ok
integerList.add(42); // Ok

System.out.println(unsafeListClass.isInstance(integerList)); // Prints "true".
List<String> stringList =
   unsafeListClass.cast(integerList); // Succeeds, with no warning!
stringList.add("Hello, World!"); // Also succeeds with no warning

for (int x: integerList) {
    // Compiles without warning, but throws ClassCastException at runtime
    System.out.println(100-x);
}
 

7voto

JRL Points 36674

Trouvé ce lien sur springframework.org qui donne un aperçu.

Par exemple

 List<String> myList = new ArrayList<String>();
return (Class<List<String>>)myList.getClass();
 

2voto

fd. Points 6835

Découvrez cette discussion sur les forums SUN:

http://forums.sun.com/thread.jspa?threadID=5253007

Et l'article de blog référencé qui décrit une solution de contournement à l'aide de "jetons de type super":

http://gafter.blogspot.com/2006/12/super-type-tokens.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X