2012-01-01 3 views
4

Pourquoi la question du compilateur un avertissement lors de la déclaration d'une variableavertissements du compilateur lors de la déclaration des types génériques

List<? extends Object> list = new LinkedList(); 

Attention:

Note: ZiggyTest.java uses unchecked or unsafe operations. 
Note: Recompile with -Xlint:unchecked for details. 

Mais il ne marche pas émettre un avertissement quand je déclare la variable

List<?> list = new LinkedList(); 
+0

Checkout http://stackoverflow.com/questions/8683137/and-extends-object/8683314 et l'excellent tutoriel de génériques dans ma réponse là-bas qui est un incontournable lorsque vous travaillez avec des génériques – Robin

+0

Il ne délivre pas de déclin comme vous l'avez mentionné dans mon NetBeans 6.9.1 avec jdk 6. – Lion

+0

Je n'utilise pas un IDE. Recevez-vous les avertissements lorsque vous compilez à partir de l'invite de ligne de commande? – ziggy

Répondre

1

Je ne peux pas expliquer pourquoi le compilateur ne les traite pas comme équivalents, mais étant donné que ce n'est pas le cas, je vais essayer d'expliquer pourquoi il refuse de le faire.

Le premier (List<? extends Object>) affirme que le type d'objets détenus dans le List sont d'un type inconnu dérivé de Object. Le deuxième (List<?>) dit moins; il dit simplement que le type des objets de la liste est inconnu. Il ne mentionne aucun supertype attendu en tant que limite supérieure du type inconnu.

Afin de vérifier la première hypothèse, le compilateur veut vous entendre dire quelque chose sur les types attendus détenus dans l'instance List construit ici comme le type brut LinkedList, qui ne dit rien sur le sujet. Cependant, si vous deviez construire l'instance en tant que type LinkedList<Object>, vous garantissez au moins que la covariant lit contre l'instance sera cohérente avec votre assertion: à savoir, que les choses dans cette liste sont une sorte de Object. Maintenant, tout cela semble stupide, car tout type de référence/non-primitif dans Java s'étend Object, donc il ne devrait y avoir aucune différence d'interprétation entre List<? extends Object> et List<?>; après tout, le second implique le premier, en vertu de la hiérarchie de classe à enracinement unique mandatée par le système de types du langage.

2

Cela apparaît dans Java 5 et versions ultérieures si vous utilisez des collections sans spécificateur de type (par exemple, Arraylist() au lieu de ArrayList<String>()). Cela signifie que le compilateur ne peut pas vérifier que vous utilisez la collection de manière sécurisée, en utilisant generics.

Pour vous débarrasser de l'avertissement, soyez précis sur le type d'objets que vous stockez dans la collection. Ainsi, au lieu de

List list = new ArrayList(); 

devrait être aussi

List<String> list = new ArrayList<String>(); 

Dans votre cas, si vous modifiez cette déclaration comme suit,

List<? extends Object> list = new LinkedList<Object>(); 

il compiler sans avertissement car Nous sommes en train de sécuriser le type en utilisant le type générique (<Object>).

+0

La nouvelle LinkedList (); 'ne compile pas – Robin

+0

Sauf que vous ne pouvez pas utiliser de caractères génériques dans les déclarations. – Voo

Questions connexes