web-dev-qa-db-fra.com

Que signifie le point d'interrogation dans Java)?

Ceci est un petit extrait de code tiré de certains des exemples qui accompagnent l'analyseur Stanford. Je développe en Java depuis environ 4 ans, mais je n’ai jamais vraiment compris ce que ce style de code est censé indiquer.

List<? extends HasWord> wordList = toke.tokenize();

Je ne m'inquiète pas des détails du code. Ce qui me rend confus, c'est ce que l'expression générique est censée exprimer exactement, en anglais.

Quelqu'un peut m'expliquer cela?

192
sholsapp
? extends HasWord

signifie "Une classe/interface qui étend HasWord." En d'autres termes, HasWord lui-même ou l'un de ses enfants ... essentiellement tout ce qui fonctionnerait avec instanceof HasWord Plus null.

En termes plus techniques, ? extends HasWord Est un caractère générique délimité, couvert dans la rubrique 31 de Effective Java 3ème édition , commençant le page 139. Le même chapitre de la 2e édition est disponible en ligne au format PDF ; la partie sur les jokers délimités est le numéro 28 à partir de la page 134.

Mise à jour: le lien PDF a été mis à jour car Oracle l'a supprimé il y a longtemps. Il se réfère maintenant à la copie hébergée par la School of Electronic Engineering and Computer Science de l’Université Queen Mary de Londres.

Mise à jour 2: Voyons un peu plus en détail pourquoi vous souhaitez utiliser des caractères génériques.

Si vous déclarez une méthode dont la signature s'attend à ce que vous transmettiez List<HasWord>, La seule chose que vous pouvez transmettre est un List<HasWord>.

Cependant, si ladite signature était List<? extends HasWord>, Vous pourriez alors passer un List<ChildOfHasWord>.

Notez qu'il existe une différence subtile entre List<? extends HasWord> Et List<? super HasWord>. Comme Joshua Bloch l'a dit: PECS = producteur-rallonge, consommateur-super.

Cela signifie que si vous transmettez une collection dont votre méthode extrait des données (c’est-à-dire que la collection produit des éléments que votre méthode peut utiliser), vous devez utiliser extends. Si vous transmettez une collection à laquelle votre méthode ajoute des données (c’est-à-dire que la collection utilise des éléments créés par votre méthode), vous devez utiliser super.

Cela peut sembler déroutant. Cependant, vous pouvez le voir dans la commande de Listsort (qui n'est qu'un raccourci vers la version à deux arguments de Collections.sort). Au lieu de prendre un Comparator<T>, Il faut en fait un Comparator<? super T>. Dans ce cas, le comparateur utilise les éléments de List afin de réorganiser la liste elle-même.

210
Powerlord

Un point d'interrogation est un signifiant pour "n'importe quel type". ? seul signifie

Tout type prolongeant Object (y compris Object)

alors que votre exemple ci-dessus signifie

Tout type développant ou implémentant HasWord (y compris HasWord si HasWord est une classe non abstraite)

55
Jherico

List<? extends HasWord> accepte toutes les classes concrètes qui étend HasWord. Si vous avez les cours suivants ...

public class A extends HasWord { .. }
public class B extends HasWord { .. }
public class C { .. }
public class D extends SomeOtherWord { .. }

... le wordList ne peut contenir UNIQUEMENT qu'une liste de As ou de Bs ou une combinaison des deux parce que les deux classes étendent le même parent ou null (ce qui échoue instanceof vérifie HasWorld ).

13
limc

Peut-être qu'un exemple de "monde réel" artificiel aiderait.

Sur mon lieu de travail, nous avons des poubelles de différentes saveurs. Tous les bacs contiennent des ordures, mais certains bacs sont spécialisés et ne prennent pas tous les types de déchets. Nous avons donc Bin<CupRubbish> et Bin<RecylcableRubbish>. Le système de types doit s'assurer que je ne peux pas placer mon HalfEatenSandwichRubbish dans l'un de ces types, mais il peut aller dans une corbeille générale Bin<Rubbish>. Si je voulais parler d'un Bin de Rubbish qui peut être spécialisé afin que je ne puisse pas mettre des ordures incompatibles, alors ce serait Bin<? extends Rubbish>.

(Remarque: ? extends ne signifie pas lecture seule. Par exemple, je peux, avec les précautions appropriées, sortir un déchet d'une poubelle de spécialité inconnue et le remettre plus tard dans un endroit différent.)

Je ne sais pas à quel point ça aide. Le pointeur à pointeur en présence de polymorphisme n'est pas tout à fait évident.

11

En anglais:

C'est un List d'un type quelconque qui étend la classe HasWord, y compris HasWord

En général, le ? par générique, n’importe quelle classe. Et le extends SomeClass spécifie que cet objet doit être étendu SomeClass (ou être cette classe).

4
jjnguy

Le point d'interrogation sert à définir des caractères génériques . Consultez la documentation Oracle à leur sujet: http://docs.Oracle.com/javase/tutorial/Java/generics/wildcards.html

1
leo9r