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 :

Generics - pb de cast


Sujet :

Langage Java

  1. #1
    Membre régulier
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Points : 102
    Points
    102
    Par défaut Generics - pb de cast
    Soit le code suivant :

    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
    public class Classe1<T>
    {
        protected T ref = null;
     
        public Classe1()
        {
            ref = (T)this;
            System.out.println(ref.getClass());
        }
     
        public static void main(String[] args)
        {
            Classe1<String> c = new Classe1<String>();
        }
    }
    L’exécution de ce code affiche dans la console :
    class Classe1

    Or je ne comprends pas pourquoi "ref" n'est pas de type String et pourquoi je n'ai pas une ClassCastException lors de l'affectation = ref = (T)this;

  2. #2
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Les génériques ne sont là que pour la compilation, dans le bytecode il n'y en a aucune trace.

    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class FooBar {
      public static void main(String[] args) {
        List<String> stringList = new LinkedList<String>();
        List list = stringList; //Warning
        list.add(Integer.valueOf(0)); // ok
        String first = stringList.get(0); // ClassCastException
      }
    }
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  3. #3
    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 Guybrush Voir le message
    Or je ne comprends pas pourquoi "ref" n'est pas de type String
    Parce que du fait de cette ligne : ref vaut simplement this, et que this est de classe Classe1

    Citation Envoyé par Guybrush Voir le message
    et pourquoi je n'ai pas une ClassCastException lors de l'affectation = ref = (T)this;
    Pour la raison donnée par le warning que te fait ton compilateur sur ce cast.
    Les génériques ne sont qu'un outil compile-time, ils servent à s'assurer de la cohérence des types à la compilation.
    Après compilation, donc entre autres au runtime, les génériques n'existent plus. T n'étant pas contraint, il sera considéré comme Object, et donc il n'y a aucun cast à faire, tout objet héritant forcément de Object. Un ClassCastException est donc impossible.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre régulier
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    merci, c'est très clair.

    Dans le même genre, pourquoi je ne peut pas écrire :

    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
    public class Classe1<T extends List>
    {
        protected T ref = null;
     
        public Classe1()
        {
            ref = (T)this;
            System.out.println(ref.getClass());
        }
     
        public static void main(String[] args)
        {
            Classe1<String> c = new Classe1<String>();
        }
    }
     
    public class Classe2<T extends ArrayList> extends Classe1<T>
    {
    }
    J'ai une erreur de compilation sur la déclaration de Classe2 avec le message :
    Bound mismatch: The type T is not a valid substitute for the bounded parameter <T extends List> of the type Classe1<T> Classe2.java

  5. #5
    Membre expérimenté
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Points : 1 640
    Points
    1 640
    Par défaut
    J'ai du mal à comprendre ta tentative d'utilisation des generics là. Avant de tenter de résoudre ton problème, peux-tu nous expliquer l'intention qui est derrière ?

    Tu as une erreur dans ton main, String ne peut pas être utilisé pour Classe1 (T extends List).
    Par ailleurs, List est générique et tu ne précises pas le type générique (List<E>), donc tu as des avertissements lors de la compilation (à la limite ce n'est pas grave).

    L'erreur que j'ai en compilant ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bound mismatch: The type String is not a valid substitute for the bounded parameter <T extends List> of the type Classe1<T>
    Ce qui est normal, String n'étend pas List.
    En premier lieu, utilisez un moteur de recherche.
    En second lieu, postez sur le forum adéquat !

  6. #6
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Classe1 (this) non plus d'ailleurs
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  7. #7
    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
    faudra que tu nous explique ce que tu essaie de faire avec ton
    Le typage générique, ce ne sont pas de paramètres passé au constructeur, ce représente juste des classe, pas des valeurs. et this n'est pas un List, c'est un Classe1<? extends List>

  8. #8
    Membre régulier
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    Citation Envoyé par Patriarch24 Voir le message
    J'ai du mal à comprendre ta tentative d'utilisation des generics là. Avant de tenter de résoudre ton problème, peux-tu nous expliquer l'intention qui est derrière ?

    Tu as une erreur dans ton main, String ne peut pas être utilisé pour Classe1 (T extends List).
    Par ailleurs, List est générique et tu ne précises pas le type générique (List<E>), donc tu as des avertissements lors de la compilation (à la limite ce n'est pas grave).

    L'erreur que j'ai en compilant ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bound mismatch: The type String is not a valid substitute for the bounded parameter <T extends List> of the type Classe1<T>
    Ce qui est normal, String n'étend pas List.
    mauvais copier/coller, desole.
    Il faut enlever le code du main qui évidemment n'a pas de sens.

    Ce que veut faire : limiter dans la classe dérivée (ici classe2) le type paramétré T aux dérivés de ArrayList.
    En gros je veux pouvoir créer des classe1 avec n'importe quel type de List, mais je ne veux créé des classe2 qu'avec des types ArrayList.

  9. #9
    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
    c'est pas le soucis, ce qu'on comprend pas, c'est ce que vous essayez de faire avec this dans le constructeur :s

  10. #10
    Membre régulier
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    c'est pas le soucis, ce qu'on comprend pas, c'est ce que vous essayez de faire avec this dans le constructeur :s
    c'était juste pour illustrer mon premier exemple.
    ma question c'est pourquoi j'ai une erreur de compilation sur la déclaration de classe2.

  11. #11
    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,


    Donnes nous le code exact + l'erreur exacte alors, car sur la déclaration de Classe2 il n'y a pas d'erreur (si ce n'est les warning dû à l'utilisation d'ArrayList sans paramétrage).


    a++

  12. #12
    Membre régulier
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Points : 102
    Points
    102
    Par défaut
    J'ai compris !!!

    La complétion d'Eclipse m'a ajouté cet import pour la déclaration de List dans Classe1 :
    import com.sun.xml.internal.bind.v2.schemagen.xmlschema.List;

    d'où le problème avec ArrayList dans classe2

  13. #13
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par Guybrush Voir le message
    J'ai une erreur de compilation sur la déclaration de Classe2 avec le message :
    Bound mismatch: The type T is not a valid substitute for the bounded parameter <T extends List> of the type Classe1<T> Classe2.java
    C'est la Classe1 du fichier Classe2.java qui pose problème pas la Classe2 !

    C'est parce que tu cherches à affecter Classe1<T> (this) dans une variable/attribut de type T extends List.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 26/04/2011, 18h00
  2. Cast d'une classe generic
    Par Seth77 dans le forum C#
    Réponses: 3
    Dernier message: 27/06/2008, 14h27
  3. Erreur de cast sur les generics!
    Par Razgriz dans le forum Général Java
    Réponses: 8
    Dernier message: 02/10/2007, 18h33
  4. [JAVA 5.0] Generics - Cast et creation d'objets
    Par bourbaki2003 dans le forum Langage
    Réponses: 12
    Dernier message: 14/03/2007, 15h34
  5. [generics] unchecked après un casting
    Par zais_ethael dans le forum Langage
    Réponses: 6
    Dernier message: 11/05/2006, 10h31

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