2011-05-19 6 views
4

Note: purement par curiosité et non pour un cas d'utilisation réel.comment déclarer Class.class avec des génériques valides

Je me demande s'il y a un moyen de déclarer l'objet ClassClass avec des paramètres de type valides:

Class cc1 = Class.class; //raw type 
Class<Class> cc2 = Class.class; //now parameter is raw type 
Class<Class<?>> cc3 = Class.class; //compile error: inconvertible types 

Si Class et Class<?> sont interchangeables, pourquoi sont Class<Class> et Class<Class<?>> pas?

EDIT: la question peut être généralisée à un problème de paramètres de type brut imbriqués. Par exemple:

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList>(); //same compile error 

EDIT2: je devrais reformuler la question un peu: je sais que

Class<?> c = Class.class; 

est valide, mais je me demande pourquoi Class<Class> n'est pas la même chose que Class<Class<?>>

Répondre

2

Les génériques ont des limitations assez sérieuses. Dans ce cas, vous ne pouvez pas affecter un type au type interne de Class<Class> car vous référencez le type brut, et non une implémentation du type brut. Il vous donnera un avertissement, mais vous n'avez aucun moyen de corriger cet avertissement. Par lui-même n'est pas un type inconvertible, vous ne pouvez pas lui attribuer une classe directement parce qu'il n'a pas le type Class<Class<T>>, il a le type Class<T>.

Pensez-y d'une autre façon; essayez List<List<String>>. Pour créer cela, vous devez créer une liste qui prend une liste de chaînes. Cela fonctionne parce que les listes peuvent contenir des listes. Une classe ressemble plus à une primitive qu'à un objet de données, donc je ne pense pas qu'il soit possible de créer une classe de type Classe d'autre chose.

Modifier: votre question supplémentaires sur ArrayList<ArrayList<?>> est un exemple plus évident de la question du type inconvertible que vous avez avec Class<Class<?>>.

+0

Les réponses ci-dessus ont donné des explications détaillées sur les génériques/caractères génériques, mais celui-ci est le plus proche de ce que je demandais, c'est pourquoi la classe n'est pas la même que la classe >. Merci à tous –

2

Il est difficile de voir exactement ce que vous demandez (ou ce que vous essayez de faire), mais vous pouvez paramétrer sans les types bruts.

Class<? extends Object> cc4 = Class.class; // no raw types 
Class<?> cc5 = Class.class; // also an option 

En ce qui concerne votre dernier exemple est concerné, il n'a pas de sens, car il semble que vous voulez faire une liste de tableau de listes de tableau qui détiennent ?, mais votre déclaration ne déclare pas une liste de tableau de listes de tableau qui détiennent ?.

correctement écrit (mais toujours pas bon Java) serait:

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList<Integer>>(); // Type mismatch 

Ce qui est prévu. Il ne fonctionne pas pour la même raison quelque chose comme ce qui suit ne fonctionne pas:

Object o = new Object(); 
Integer i = new Integer(3); 

o = i; 
i.floatValue(); 
o.floatValue(); // can't access that method, we need to specifically cast it to Integer 

types Java ne sont pas de manière proactive inférées (même dans une chaîne d'héritage).

Si vous souhaitez conserver le caractère générique là-dedans, vous êtes invités à, si:

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList<?>>(); // works! 
+1

Réponse parfaite. Mais je dois souligner que 'est exactement la même chose que' ', c'est la seule raison pour laquelle l'expression correspond. –

2

La règle ici est que le type générique sur le côté gauche doit correspondre au type générique dans le côté droit .

Class<?> signifie une classe de tout type.

Class<?> c = Class.class; 

Fonctionne car Classe de tout type peut être Class<Class>.

Class<Class<?>> cc3 = Class.class; 

Ne pas travailler, car le type Class.class est Class<Class> qui est pas de type Class<Class<?>>

ArrayList<ArrayList<Integer>> lst = new ArrayList<ArrayList<Integer>>(); 
ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList<?>>(); 

fonctionne parce que le match deux expressions.

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList>(); 

Ne correspond pas.

Questions connexes