1056 votes

Différence entre < ? super T> et < ? extends T> en Java

Quelle est la différence entre List<? super T> y List<? extends T> ?

J'avais l'habitude d'utiliser List<? extends T> mais il ne me permet pas d'y ajouter des éléments. list.add(e) alors que le List<? super T> fait.

41 votes

Consultez cet excellent exposé : youtu.be/V1vQf4qyMXg?t=22m24s

1 votes

Ici null nous pouvons ajouter

0 votes

Une très bonne explication avec un exemple @ youtube.com/watch?v=34oiEq9nD0M&feature=youtu.be&t=1630 qui explique la partie < ? super T> mais, donne une idée d'une autre.

21voto

Istao Points 2764

Super est une borne inférieure, et extends est une borne supérieure.

Selon http://download.oracle.com/javase/tutorial/extra/generics/morefun.html :

La solution consiste à utiliser une forme de de wildcards bornés que nous n'avons pas encore vue : des jokers avec une limite inférieure. La syntaxe syntaxe ? super T désigne un type inconnu inconnu qui est un supertype de T (ou de T lui-même ; rappelez-vous que la relation supertype est réflexive). C'est le double des jokers délimités que nous avons utilisés, où nous utilisons ? extends T pour pour désigner un type inconnu qui est un sous-type de T.

14voto

elyor Points 545

Ajout d'un élément à la liste :

  • Liste< ? étend X > ne permet pas d'ajouter quoi que ce soit, à l'exception de null dans la liste.

  • Liste< ? super X > permet d'ajouter tout ce qui est-a X (X ou son sous-type), ou null.

Récupérer un élément de la liste :

  • Lorsque vous obtenez un élément de Liste< ? étend X > vous pouvez l'affecter à une variable de type X ou à n'importe quel supertype de X, y compris Object.
  • Lorsque vous obtenez un élément de Liste< ? super X > vous ne pouvez l'affecter qu'à une variable de type Object .

Quelques exemples :

    List<? extends Number> list1 = new ArrayList<Integer>();
    list1.add(null);  //OK
    Number n = list1.get(0);  //OK
    Serializable s = list1.get(0);  //OK
    Object o = list1.get(0);  //OK

    list1.add(2.3);  //ERROR
    list1.add(5);  //ERROR
    list1.add(new Object());  //ERROR
    Integer i = list1.get(0);  //ERROR

    List<? super Number> list2 = new ArrayList<Number>();
    list2.add(null);  //OK
    list2.add(2.3);  //OK
    list2.add(5);  //OK
    Object o = list2.get(0);  //OK

    list2.add(new Object());  //ERROR
    Number n = list2.get(0);  //ERROR
    Serializable s = list2.get(0);  //ERROR
    Integer i = list2.get(0);  //ERROR

6voto

Shailesh Pratapwar Points 2171

Les réponses votées couvrent les détails de nombreux aspects. Cependant, je voudrais essayer de répondre à cette question d'une manière différente.

Il y a 2 choses que nous devons considérer,

1. Assignation à la variable liste

List<? extends X> listvar;

Ici, tout la liste de X ou la liste des sous-classes de X peuvent être assignées à listvar.

List<? extends Number> listvar; listvar = new ArrayList<Number>(); listvar = new ArrayList<Integer>();


List<? super X> listvar;

Ici, tout la liste de X ou la liste des superclasses de X peuvent être affectées à listvar.

List<? super Number> listvar; listvar = new ArrayList<Number>(); listvar = new ArrayList<Object>();

2. Effectuer une opération de lecture ou d'écriture sur la variable liste

`List<? extends X> listvar;`

Vous pouvez utiliser cette fonctionnalité pour accepter une liste d'arguments de méthode et effectuer toutes les opérations sur les éléments suivants type X (Note : Vous pouvez lire uniquement les objets de type X de la liste).

`List<? super Number> listvar;

Vous pouvez utiliser cette fonctionnalité pour accepter une liste d'arguments de méthode et effectuer toutes les opérations sur les éléments suivants type Objet comme vous le pouvez lire uniquement les objets de type Object de la liste. Mais oui, la chose supplémentaire ici est que vous pouvez ajouter des objets de type X dans la liste.

5voto

Sai Sunder Points 392

Utilisation de étend que vous ne pouvez obtenir que de la collection. Vous ne pouvez pas y entrer. De plus, bien que super permet à la fois le get et le put, le type de retour lors du get est ? super T .

5voto

jforex78 Points 90

Vous pouvez passer en revue toutes les réponses ci-dessus pour comprendre pourquoi la .add() est limité à '<?>' , '<? extends>' et en partie à '<? super>' .

Mais voici la conclusion de tout cela si vous voulez vous en souvenir, et si vous ne voulez pas explorer la réponse à chaque fois :

List<? extends A> signifie qu'il acceptera toute List de A et sous-classe de A . Mais vous ne pouvez rien ajouter à cette liste. Pas même les objets de type A .

List<? super A> signifie qu'il acceptera toute liste de A et superclasse de A . Vous pouvez ajouter des objets de type A et ses sous-classes.

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