IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Embrouillé par l'opérateur "wildcard"


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    173
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 173
    Par défaut Embrouillé par l'opérateur "wildcard"
    Bonjour,

    J'ai toujours compris par : List<?extends B> list que list acceptera des elements de type héritant de B. (On descends dans l'arbre des classes)

    Et List<? super B> list que list acceptera des elements de type dont B hérite (On remonte dans l'arbre des classes).

    Alors pourquoi ce qui suit ne compile pas??

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    class A{}
     
    class B extends A{}
     
    class C extends B{}
     
    public class Test {
     
    	public static void main(String[] args) {
     
    		List<? extends B> list = new ArrayList<B>();
    		list.add(new B());
    		list.add(new C());
     
    		List<? super B> list1 = new ArrayList<A>();
    		list.add(new B());
    		list.add(new A());
    	}
     
    }
    D'autre part à quoi ca sert de définir <? extends B> puisque le polymorphisme permet deja cela.

    A l'aide

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Ce n'est pas tout à fait cela.
    Les wildcards permettent de travailler avec des objets paramétrés dont tu ne connais pas le type exact, afin d'écrire un code plus générique.

    En effet les types Generics sont fortement typé et donc fortement incompatible. Si B hérite de A, tu as le droit de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    A b = new B();
    A[] array = new B[10];
    Par contre tu n'as pas le droits de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<A> list = new ArrayList<B>(); // NE COMPILE PAS
    En effet en cas d'ajout de mauvais éléments dans la liste (par exemple une classe C héritant de A mais pas de B) : tu casses la contrainte de type de la liste ce qui devrait provoquer une exception à l'exécution (alors que l'objectif des Generics est d'éviter cela).

    Les wildcards interviennent alors afin de proposer une version "diminué" mais un peu plus compatible sous certaines contrainte.


    En fait lorsque tu utilises List<? extends A>, tu sais que tu manipules une List paramétrée avec A ou un type héritant, sans connaitre exactement lequel. Du coup tu peux lire les éléments de la liste (tu es sûr qu'ils sont du type A), mais tu ne peux pas ajouter des éléments dans la liste (car tu ne connais pas le type exact qu'il faut ajouter).


    Par exemple si tu as une liste déclarée comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<Integer> listIntegers = new ArrayList<Integer>();
    Tu ne peux pas faire cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<Number> listNumbers = listIntegers; // ERREUR
    Et donc tu dois passer par les wildcards qui t'empêcheront d'utilsier certaines méthodes afin de conserver la cohérence des types, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    List<? extends Number> listNumbers = listIntegers;
     
    Number value = listNumbers.get(0); // OK
    listNumbers.add(10); // ERREUR car on ne connait pas le type exact de la liste

    Les <? super X> c'est pareil dans le sens inverse : tu peux ajouter des éléments mais tu ne connais pas le type réel des éléments à lire...


    Je ne sais pas si c'est clair...



    a++

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 586
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 586
    Par défaut
    Ma propre formulation :

    - List<?> : liste de trucs dont on ne sait pas ce que c'est.
    -- Fournit des Object, parce que tout objet est un Object
    -- N'accepte aucune entrée, parce qu'on ne sait pas ce que ça contient, et donc on ne sait pas ce qu'on peut y mettre.
    -- On peut affecter n'importe quel List à un List<?>.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<?> list = new ArrayList<Date>();
    - List<? extends A> : liste de trucs dont on ne sait pas ce que c'est, mais qui, au moins, sont A ou sous-classe de A.
    -- Fournit des A.
    -- N'accepte aucune entrée, parce qu'on ne sait pas ce que ça contient.
    -- On peut affecter à List<? extends A> toute List dont on sait que le contenu étend A.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    List<? extends A> list = new ArrayList<A>();
    // Soit B une sous-classe de A...
    List<? extends B> listB = getListB();
    List<? extends A> listA = listB
    Note : List<?> est un raccourci pour List<? extends Object>

    - List<? super A> : liste de trucs dont on ne sait pas ce que c'est, mais en tout cas des trucs auxquels on peut affecter des A.
    -- Fournit des Object, parce qu'on ne sait pas ce que ça contient.
    -- Accepte des A en entrée.
    -- On peut affecter à List<? super A> toute List qui accepte des A en entrée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    List<? super A> list = new ArrayList<A>();
    // Soit B une sur-classe de A...
    List<? super B> listB = getListB();
    List<? super A> listA = listB
    - List<A> : liste de A.
    -- Fournit des A.
    -- Accepte des A en entrée.
    -- On ne peut y affecter que des List de A.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    173
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 173
    Par défaut
    Merci,

    Maintenant c'est plus clair.

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo