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 :

Listes paramétrées et conversions


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2004
    Messages : 219
    Par défaut Listes paramétrées et conversions
    Bonjour,

    J'ai un problème de cast avec mes listes paramétrées. Voici un exemple permettant d'illustrer ce que je veux faire, ça sera mieux qu'une dizaine de lignes de texte

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public interface TestModel {
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public interface TestMutableModel extends TestModel {
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public class Test implements TestMutableModel {
        public Test() {
        }
    }
    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 Main {
        public static void main(String args[]) {
            // Ok ca marche.
            TestModel tm;
            TestMutableModel tmm = new Test();
            tm = tmm;
     
            // KO Ca ne marche pas!
            List<TestModel> ltm;
            List<TestMutableModel> ltmm = new ArrayList<TestMutableModel>();
            ltm = ltmm; // Impossible.
            ltm = (List<TestModel>) ltmm; // Impossible aussi évidemment.
        }
    }
    Je ne sais pas comment faire, sans me passer des generics. Quelqu'un aurait une solution élégante ?

    Merci

  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,



    C'est normal que ce ne soit pas possible, car si ce code était autorisé tu pourrais faire ceci par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    List<TestMutableModel> ltmm = new ArrayList<TestMutableModel>();
    List<TestModel> ltm; = (List<TestModel>) ltmm; // Impossible
     
    ltm.add( new MonAutreClasseQuiImplementeTestModel() );
    Bref tu ajoutes dans ltm une classe qui implémente TestModel mais pas TestMutableModel. Or comme ltm et ltmm représente la même liste cela veut dire que tu ajoutes dans ltmm un objet qui n'implémente pas TestMutableModel tu casses la protection des generics !


    Pour pallier à cela tu as deux solutions :
    1. Créer une copie de la liste contenant les mêmes éléments :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      	List<TestMutableModel> ltmm = new ArrayList<TestMutableModel>();
      	List<TestModel> ltm = new ArrayList<TestModel>(ltmm);
      Si tu modifies ltm cela n'aura aucun impact sur ltmm...


    2. Ou utiliser les wilcards qui permettent de limiter l'utilisation de la classe :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      	List<TestMutableModel> ltmm = new ArrayList<TestMutableModel>();
      	List<? extends TestModel> ltm = ltmm;
      Ici ltm et ltmm représente toujours la même liste en mémoire, mais ltm est limité et tu ne pourras pas utiliser toutes ses méthodes. Ainsi toutes les méthodes qui attendent un type paramétré en paramètre sont inutilisable puisque le type paramétré exact est inconnu.
      Bref tu ne pourras pas faire :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ltm.add( "...n'importe quoi..." );
      Par contre tu pourras toujours utiliser les méthode qui n'utilises pas de type paramétré ou qui se contente de le renvoyer :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      	TestModel tm = ltm.get(0);


    Plus d'info : Présentation de Java 5.0 - Les Generics

    a++

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2004
    Messages : 219
    Par défaut
    Je te remercie, pour ces explications. La solutution 2 ne convient pas car j'ai besoin d'accéder aux méthode définies dans l'interface mutable.
    La solution 1 serait donc à adopter mais je suis pas sûr que ça soit bien ce que j'ai fait. Voici un exmple simplifié plus concret de ce que je veux faire :

    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
     
    public class Chapter implements ChapterMutableModel {
     
        private List<ExerciseMutableModel> exercises;
     
        public Chapter() {
            this.exercises = new ArrayList<ExerciseMutableModel>();
        }
     
        public Chapter(List<ExerciseMutableModel> exercises) {
            this.exercises = exercises;
        }
     
        public void setExercises(List<ExerciseMutableModel> exercises) {
            this.exercises = exercises;
        }
     
        public List<ExerciseModel> getExercises() {
            return Collections.unmodifiableList(new ArrayList<ExerciseModel>(this.exercises));
        }
    }

  4. #4
    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
    Citation Envoyé par TheSeb Voir le message
    Je te remercie, pour ces explications. La solutution 2 ne convient pas car j'ai besoin d'accéder aux méthode définies dans l'interface mutable.
    Heu... comme tu renvois une liste de ExerciseModel donc tu ne pourras pas utiliser les méthodes de l'interface mutable...
    De plus tu renvoi une liste non modifiable donc la protections des wilcards est un p'tit plus à la compilation (cela t'interdira d'appeler les méthodes add()).

    Pour moi tu pourrais très bien faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        public List<? extends ExerciseModel> getExercises() {
            return Collections.unmodifiableList(this.exercises);
        }
    a++

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2004
    Messages : 219
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Heu... comme tu renvois une liste de ExerciseModel donc tu ne pourras pas utiliser les méthodes de l'interface mutable...
    De plus tu renvoi une liste non modifiable donc la protections des wilcards est un p'tit plus à la compilation (cela t'interdira d'appeler les méthodes add()).
    Ah oui mince, c'est pile poil ce qu'il me faut dans ma méthode getExercises.
    J'avais dans la tête l'initialison de ma variable comme ca au début : private List<? extends ExerciseModel> exercises; ... bref je me demande à quoi je pense des fois Je vérifierai quand même que tout ca fonctionne comme je le voulais ce soir chez moi.

    Merci.

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

Discussions similaires

  1. Liste paramètres imbriqués
    Par brachior dans le forum C#
    Réponses: 26
    Dernier message: 09/06/2011, 12h15
  2. [AC-2003] comportement différent suivant les pc - liste paramétrée
    Par Dermochelys dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 04/04/2011, 13h35
  3. Paramètres de conversion simplifiée vers Lambert93
    Par Max_B dans le forum IGN API Géoportail
    Réponses: 3
    Dernier message: 07/09/2010, 14h01
  4. [AC-2003] Table avec un champ liste paramétré
    Par lio33 dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 17/06/2010, 15h24
  5. [LIST] Problème de conversion de chaînes de caractères
    Par yannick29000 dans le forum Autres langages
    Réponses: 0
    Dernier message: 31/07/2009, 12h10

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