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 :

[Généricité] Un échec de compilation qui s'explique précisément par?


Sujet :

Langage Java

  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut [Généricité] Un échec de compilation qui s'explique précisément par?
    Bonjour,


    J'écrivais un petit code de démonstration, et j'ai rencontré un obstacle inattendu.

    Avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public abstract class Fruit extends Produit implements Périssable {...}
    et
    public class Pomme extends Fruit {...}

    J'ai écrit ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Expérimentation
    {
       public <P extends Fruit> Vector<P> liste()
       {
          Vector<P> liste = new Vector<P>();
     
          Pomme pomme = new Pomme("Pomme rouge");
          liste.add(pomme);
     
          Fruit f = liste.get(0);
     
          return(liste);
       }
    }
    La compilation échoue sur un message "The method add(P) in the type Vector<P> is not applicable for the arguments (Pomme)".

    Et pourtant, Pomme hérite bel et bien de Fruit!
    Je peux essayer une grande variété d'instructions qui fonctionnent et qui le montrent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Fruit f = liste.get(0);
    ou
    Vector<? extends Fruit> liste = new Vector<Pomme>();

    Mais le add(pomme) dans le vecteur, lui, ne passe pas.

    Bien entendu, si je modifie le prototype de ma fonction en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public Vector<Pomme> liste()
    ou
    public Vector<Fruit> liste()
    et que j'adapte son code en conséquence, tout rentrera dans l'ordre. Mais:
    - Ce n'est pas ce que je veux.
    - Cela ne me donnera pas pour autant l'explication du problème de compilation qui se pose.


    J'ai fait l'hypothèse que ce qui empêche Java de compiler mon programme c'est qu'à la compilation il procède au type erasure pour rendre son code binairement compatible 1.4.

    Et qu'alors, il se dit:

    Avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public Vector<Pomme> liste()
     
    je dois simuler cette invocation:
    Vector.add(Pomme p)
    Avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public Vector<Fruit> liste()
     
    je dois simuler cette invocation:
    Vector.add(Fruit f)
    et dans les deux cas, je peux faire une assertion sur le paramètre d'entrée et le simplifier en un type unique.

    Mais avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public <P extends Fruit> Vector<P> liste()
     
    je dois invoquer:
    Vector.add(? extends Fruit f)
    Et là, je ne peux pas remplacer ? extends Fruit par une classe unique puisque cela pourrait être n'importe quelle classe dérivée de Fruit.

    Mais cette explication ne me convient pas entièrement, car ? extends Fruit est une expression qui admet Fruit comme classe.

    Donc, Java devrait pouvoir faire l'assertion que la méthode add(...) à appeler a pour prototype minimal garanti: Vector.add(Fruit f)?


    Quel explication donnez-vous à ce qui se produit?

    Je vous remercie!

    Grunt.

  2. #2
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par grunt2000 Voir le message
    Donc, Java devrait pouvoir faire l'assertion que la méthode add(...) à appeler a pour prototype minimal garanti: Vector.add(Fruit f)?
    Le compilateur vérifie la cohérence de l'ensemble du code utilisant les Generics, et produit des warnings/erreurs en cas de problème.

    On utilise le wildcard ? extends pour indiquer qu'on ne connait pas le paramétrage précis, ce qui nous donne un accès partiel aux méthodes de la classe Generics.

    Dans ton cas, avec Vector<? extends Fruit> tu peux récupérer les éléments du vecteur (car tu sais que ce seront des Fruits ou un type fils quelconques), par contre tu ne peux pas y ajouter des éléments car tu ne sais pas quel est le type d'objet exact qui est attendu par le vecteur.

    Tu veux y ajouter des Pommes, mais rien ne garantie que la liste ne devrait pas être limité aux Bananes ou aux Oranges par exemple...


    Les wildcard sont surtout utilisé pour faire un code générique qui ne soit pas limiter à un type précis, mais je n'y vois pas vraiment d'intérêt dans ton cas...



    a++

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Dans cet extrait, l'intérêt de <P extends Fruit> est faible, mais je voulais à terme rajouter des références à P dans les paramètres d'entrée de la fonction.

    Ce qui m'intrigue, c'est qu'il me semble que Java devrait se sortir de cette situation. Il ne peut déterminer quel est la limite de la classe "en spécialisation" (Banane, Orange, Pomme, etc.) mais il est sûr de celle "en généricité": c'est Fruit. Donc, il devrait pouvoir (à mon sens) l'accepter.
    Car add(Fruit f) est supposé accepter tout ? extends Fruit.

    Je ne vois pas d'ambiguïté, ou de cas où cela pourrait réellement coincer.

    Grunt.

  4. #4
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    Je ne vois pas d'ambiguïté, ou de cas où cela pourrait réellement coincer.
    Tu ne connais pas le type précis de la liste, donc tu ne peux pas y ajouter d'élément.

    Par exemple si tu fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        List<? extends Fruit> list = ...
        list.add(new Pomme("Pomme rouge")); // Erreur de compilation
    Tu ajoutes une Pomme dans une liste dont tu ne connais pas le paramétrage exact. Le compilateur ne peut donc pas t'assurer que ce code sera valide sans erreur lors de l'exécution, et il génère donc une erreur.

    Ainsi si la liste est déclarée comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        List<? extends Fruit> list = new ArrayList<Pomme>();
    Cela pourrait marcher (si c'était autorisé par le langage).

    Mais si la liste est déclarée comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        List<? extends Fruit> list = new ArrayList<Banane>();
    Ce serait incorrect car tu ajouterais une Pomme dans une liste censé contenir uniquement des Bananes


    Les wildcards te donne une vision limité sur l'objet, c'est normal et c'est voulu puisque tu ne connais pas le type exact.




    Ceci est la base même de l'objectif des Generics : générer un code typesafe qui ne génèrera pas d'erreur de typage à l'exécution.

    C'est le principe inverse des tableaux, avec lesquelles un code peut compiler parfaitement mais générer des erreurs à l'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        Fruit[] fruits = new Pomme[5];
     
        fruits[0] = new Banane(); // java.lang.ArrayStoreException


    Plutôt que de t'entêter à utiliser les wildcards de cette manière, expliques précisément ce que tu voudrais faire...



    a++


    PS : Et il y a une raison pour que tu utilises des Vectors à la place des List/ArrayList ???

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    pour montrer simplement le problème, "supposons" que ton code marche, on pourrais alors écrire ceci

    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
    public class Expérimentation
    {
       public <P extends Fruit> Vector<P> liste()
       {
          Vector<P> liste = new Vector<P>();
     
          Pomme pomme = new Pomme("Pomme rouge");
          liste.add(pomme);
     
          Fruit f = liste.get(0);
     
          return(liste);
       }
       // .....
       Vector<Banane> bananes = liste ();
       // et avoir une pomme dans notre liste de bananes? -> ben non c'est pas possible.
    }
    Dans ton cas, le code correct c'est soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Expérimentation
    {
       public Vector<Fruit> liste()
       {
          Vector<Fruit> liste = new Vector<Fruit>();
     
          Pomme pomme = new Pomme("Pomme rouge");
          liste.add(pomme);
          // on pourrais aussi mettre des bananes si on veux!
     
          return(liste);
       }
    }
    soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class Expérimentation{
       public <P extends Fruit> Vector<P> liste(P elements)
       {
          Vector<P> liste = new Vector<P>();
          liste.add(element);
          return(liste);
       }
       // ....
       Vector<Pomme> pommes = liste(new Pomme("une pomme"));
       Vector<Banane> bananes = liste(new Banane("une banane"));
    }

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Je souhaiterais atteindre ce prototype final:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public <P extends Fruit> Vector<P> liste(Class<P> classeProduit)
    {
       Vector<P> liste = ... Instanciation du vecteur approprié ...
     
       .. alimentation ..
     
       return(liste);
    }

    Pour pouvoir l'employer ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Vector<Banane> bananes = panier.liste(Banane.class);
    Vector<Pomme> pommes = panier.liste(Pomme.class);

  7. #7
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    Car add(Fruit f) est supposé accepter tout ? extends Fruit.
    C'est le contraire, un wildcard ? n'accepte rien. Du tout. Il donne, et donne seulement.

    Quant à P extends Fruit, il accepte en effet des P. Donc on peut lui add(P p). Or un Fruit n'est pas un P. C'est l'inverse : un P est un Fruit.

    Citation Envoyé par grunt2000 Voir le message
    Je ne vois pas d'ambiguïté, ou de cas où cela pourrait réellement coincer.
    En effet, il n'y a pas d'ambiguïté.
    C'est un Vector de P, et on sait que P est une sous-classe de Fruit. Donc un Fruit n'est pas assignable à un P, donc on ne peut pas donner de Fruit au Vector.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Citation Envoyé par thelvin Voir le message
    C'est un Vector de P, et on sait que P est une sous-classe de Fruit. Donc un Fruit n'est pas assignable à un P, donc on ne peut pas donner de Fruit au Vector.
    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
    import java.io.File;
     
    public class Toto<X extends File>
    {
       public void ouvrir(X fichier)
       {
          throw(new RuntimeException("Non, je n'ouvrirai pas votre fichier " + fichier.getName()));
       }
    }
     
    public class Expérimentation
    {
       public static void main(String[] args)
       {
          Toto<File> t = new Toto<File>();
          t.ouvrir(new File(""));
       }
    }
    ? extends File accepte File.
    Et c'est bien un P que l'on veut donner au vecteur de P(s).

  9. #9
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    Je souhaiterais atteindre ce prototype final
    Dans ce cas c'est différent car tu es sûr d'ajouter le bon type dans la liste, car tu ajoutes réellement un objet du type P.

    Bon par contre il faut passer par de la reflection, et j'ai toujours du mal à en saisir l'intérêt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        public <P extends Fruit> Vector<P> liste(Class<P> classeProduit) {
            Vector<P> liste = new Vector<P>();
            try {
                liste.add(classeProduit.newInstance());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return (liste);
        }
    a++

  10. #10
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Bon par contre il faut passer par de la reflection, et j'ai toujours du mal à en saisir l'intérêt :
    L'intérêt est très simple.
    Tu as un sac de courses, et l'on te demande de prendre toutes les pommes qui sont dedans (pour en faire immédiatement une tarte aux pommes, mettons).

    En réalisant cette fonction générique, tu es sûr de donner à ton appelant une liste qui ne contient que des pommes. Et qui est typée avec Pomme, le type le plus contraint existant, et non pas Fruit.

    Ce qui permettra à l'appelant d'utiliser directement sur les objets de sa liste des méthodes spécifiques à la pomme.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(Pomme p : panier.liste(Pomme.class))
       p.éplucher();
    Ce qu'il n'aurait pas pu faire si on lui avait seulement renvoyé un vecteur de Fruit(s). Là, il aurait du caster et même avant faire un instanceof pour être sûr de son coup. (parce que Fruit n'a pas la méthode éplucher() dessus: tous les fruits ne sont pas épluchables (raisin, groseilles, etc.)).

    Et c'est (je crois!) la seule solution.
    Sinon multiplier les méthodes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Vector<Pomme> listePommes();
    Vector<Banane> listeBananes();
    Vector<Orange> listeOranges();
    Mais ce n'est pas très acceptable.


    Grunt

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    dans ce cas, le code "normal" (et logique en somme) serait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    private List<Fruit> lePanier;
    // c'est notre méthode qui checke la validité, plus le compilateur!!
    @SuppressWarnings("unchecked")
    public <P extends Fruit> List<P> liste(Class<P> type) {
        List<P> liste = new ArrayList<P>();
        for (Fruit f : lePanier)
            if (type == f.class) // on aurait pu aussi utiliser type.isAssignableFrom(f.class)
                liste.add((P)f); // on peut car on vient de vérifier le typage
        return liste;
    }

  12. #12
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Tout à fait, tchize!

  13. #13
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    ? extends File accepte File.
    Pas du tout.
    Ton code montre qu'un Toto<File> accepte un File.
    Donc File accepte File. Doh !

    Tu ne peux pas expérimenter les paramètres de méthode avec des paramètres de classe.
    Enfin, pas avant de bien comprendre quelles questions se posent pour l'un et quelles questions se posent pour l'autre.


    Citation Envoyé par grunt2000 Voir le message
    Et c'est bien un P que l'on veut donner au vecteur de P(s).
    Moi dans ton code, je t'ai vu lui filer des Pomme, pas des P.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  14. #14
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Pas du tout.
    Ton code montre qu'un Toto<File> accepte un File.
    Donc File accepte File. Doh !
    Mais c'est bien ce que dit mon code: X extends File.
    Donc ça marche avec File.

    Et si
    class Fichier extends File

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Toto<Fichier> t = new Toto<Fichier>();
    t.ouvrir(new Fichier(""));
    fonctionne aussi.


    Et c'est même le but du P extends Fruit.

    Faire que P remplace toute classe qui étend ou est un Fruit, et se transforme en une classe concrète. C'est moi qui ne vois plus où est ton problème, à présent.

  15. #15
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    Tu as un sac de courses, et l'on te demande de prendre toutes les pommes qui sont dedans (pour en faire immédiatement une tarte aux pommes, mettons).
    Donc tu veux filtrer une liste... Pourquoi ne pas l'avoir dit plus tôt


    Citation Envoyé par tchize_ Voir le message
    dans ce cas, le code "normal" (et logique en somme) serait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            if (type == f.class) // on aurait pu aussi utiliser type.isAssignableFrom(f.class)
    A noter toutefois que ce n'est pas exactement la même chose. (type==f.getClass()) te renverra uniquement les objets strictement du même type, alors qu' isAssignableFrom() te renverra également les éventuelles classes filles (par exemple PommeGolden extends Pomme).

    Mais perso j'aurai plutôt utilise isInstance() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            if (type.isInstance(f))



    Citation Envoyé par grunt2000 Voir le message
    ? extends File accepte File.
    Et c'est bien un P que l'on veut donner au vecteur de P(s).
    Ce n'est pas ? extends File mais X extends File ce qui est différent.
    Tu ne connais pas le type exact de X mais tu sais que c'est le même.
    De plus à l'utilisation tu définis un type concret.

    Avec ? tu ne connais pas le type, et tu ne peux pas garantir qu'un type quelconque soit compatible avec ce que tu ne connais pas.


    a++

  16. #16
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    Mais c'est bien ce que dit mon code: X extends File.
    Donc ça marche avec File.

    Et si
    class Fichier extends File

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Toto<Fichier> t = new Toto<Fichier>();
    t.ouvrir(new Fichier(""));
    fonctionne aussi.
    Tout cela est exact mais n'a pas la moindre importance.

    Ce que tu manipules, c'est un Toto<Fichier> ou un Toto<File>.
    Ce n'est pas un Toto<X extends File> et encore moins un Toto<? extends File>
    C'est ça qui est important.

    Citation Envoyé par grunt2000 Voir le message
    Et c'est même le but du P extends Fruit.
    C'est peut-être le même but, mais là ce que tu manipules, c'est un Vector<P>, pas un Vector<Fruit>.
    Pour autant que je sache, tu n'as pas encore essayé de manipuler un Toto<X> n'est-ce pas ?
    C'est différent.

    Citation Envoyé par grunt2000 Voir le message
    Faire que P remplace toute classe qui étend ou est un Fruit, et se transforme en une classe concrète.
    Oui mais P ne "remplacera toute classe" que du point de vue des appelants de sa méthode.

    Du point de vue de la méthode elle-même, la méthode a déjà été appelée (elle est en cours d'exécution,) et P a déjà été fixé, soit à un type précis, soit à un paramétrage plus précis que celui exprimé.

    Quoi qu'il en soit, on ne sait pas précisément ce qu'est P, on sait juste qu'il étend Fruit.
    (Bien sûr, si tu passes aussi le paramètre Class<P>, là on sait très bien ce qu'est P, certes, puisque c'est ça un objet Class... Mais ça n'empêche que ta conception des génériques était erronnée.)

    Citation Envoyé par grunt2000 Voir le message
    C'est moi qui ne vois plus où est ton problème, à présent.
    Juste pour information, ce n'est pas moi qui suis venu poser des questions sur les génériques Java. Ça m'a pris du temps, mais je les comprends parfaitement.

    Il me semblait que tu avais une question, genre pourquoi ça compile pas. Moi je le sais. J'ai aussi décidé de corriger quelques erreurs que tu exprimes, car je sais que ce sont des erreurs.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  17. #17
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par adiGuba Voir le message

    A noter toutefois que ce n'est pas exactement la même chose. (type==f.getClass()) te renverra uniquement les objets strictement du même type, alors qu' isAssignableFrom() te renverra également les éventuelles classes filles (par exemple PommeGolden extends Pomme).
    C'est bien pour ça que j'ai indiqué les deux possibilité :p

Discussions similaires

  1. Compilation qui plante
    Par cotede2 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 21/04/2009, 12h15
  2. Réponses: 3
    Dernier message: 14/04/2009, 11h29
  3. Qui pourrait expliquer mon pb de core dump ?
    Par seb9999 dans le forum C
    Réponses: 10
    Dernier message: 02/03/2007, 18h06
  4. compilation qui s'arrête
    Par Grecko dans le forum Dev-C++
    Réponses: 5
    Dernier message: 08/01/2007, 15h17
  5. Pb de compilation qui me stresse ...
    Par fredoun dans le forum CORBA
    Réponses: 1
    Dernier message: 19/05/2004, 17h46

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