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

Java Discussion :

Les génériques en Java


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 262
    Par défaut Les génériques en Java
    Bonjour , en faite je suis entrain de lire un livre sur les generiques et les collections , et y'a un exemple qui m'a stoppé et j'arrive pas à comprendre : voici l'exemple:

    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
    22
    23
    24
    25
    class Promote {
     
        public static List<String> promote(List<Object> objs) {
            for (Object o : objs) {
                if (!(o instanceof String)) {
                    throw new ClassCastException();
                }
            }
            return (List<String>) (List<?>) objs; // unchecked cast
        }
     
        public static void main(String[] args) {
            List<Object> objs1 = Arrays.<Object>asList("one", "two");
            List<Object> objs2 = Arrays.<Object>asList(1, "two");
            List<String> strs1 = promote(objs1);
            assert (List<?>) strs1 == (List<?>) objs1;
            boolean caught = false;
            try {
                List<String> strs2 = promote(objs2);
            } catch (ClassCastException e) {
                caught = true;
            }
            assert caught;
        }
    }
    Ce que j'ai pas compris c'est dans la méthode promote, cette ligne là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (List<String>)(List<?>)objs; // unchecked cast
    moi je pense qu'on peut se contenter de faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (List<String>)objs;
    Pourquoi on a du convertir la liste d'object en une liste<?> puis en une liste de String.
    Merci beaucoup pour vos explications.

    J'ai oublié de dire que l'exemple permet de convertir une liste d’objects en liste de String.

  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,


    Perso je trouve cela super-crade (d'ailleurs le compilateur génère des warning !).
    Si on utilise des Generics c'est pour utiliser un type précis, pas pour utiliser Object. Ce genre de conversion est bien bizarre et il est un peu étrange d'avoir besoin de cela...



    Sinon, on ne peut pas se contenter d'un return (List<String>)objs; car le compilateur va générer une erreur : objs est un List<Object> et il ne peut pas être caster en List<String>.

    "L'astuce" consiste à rajouter un cast vers List<?> au milieu pour empêcher le compilateur de vérifier le typeage.
    Du coup le cast d'un List<?> vers un List<String> est autorisé (principalement pour des raisons de compatibilités ascendante).

    Mais il est erroné de faire cela !
    D'ailleurs le compilateur le signale par un warning "unchecked cast", qui se libère de sa responsabilité envers la vérification du typeage.

    En clair le compilateur ne garantie plus que le typeage soit correcte, et cela pourrait très bien générer des ClassCastException.


    Exemple :
    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
            List<Object> objs = new ArrayList<Object>();
            objs.add("Hello");
            objs.add("World");
     
            List<String> strs = promote(objs); // OK
     
            for (String s : strs) {
            	System.out.println(s); // OK
            }
     
            objs.add(new Date());
     
            for (String s : strs) {
            	System.out.println(s); // ClassCastException: java.util.Date
            }


    Bref c'est le genre de code à éviter !


    a++

  3. #3
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Dans le cas rarissime où on a bel et bien généré une List<Object> car elle pouvait contenir n'importe quoi, mais qu'on atteint un état où on est désormais convaincu que la List ne devrait contenir que des String et qu'il faudrait l'exploiter sous forme de List<String>,

    je préfère m'en rendre certain en construisant une nouvelle List<String> au lieu d'essayer de "convertir" la List<Object>.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public static List<String> asStrings(List<Object> objs) {
      List<String> strings = new ArrayList<>();
      for (Object o : objs) {
        strings.add((String)objs); // ClassCastException si on s'est trompé
      }
      return strings;
    }
    C'est moins efficace, mais en cas d'erreur on le sait tôt, grâce au compilateur et au cast au plus tôt.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. Réponses: 1
    Dernier message: 29/01/2015, 00h51
  2. T extends E : Java et les génériques dans l'héritage
    Par thierryler dans le forum Général Java
    Réponses: 3
    Dernier message: 11/04/2014, 15h13
  3. Java et les Génériques
    Par didate dans le forum Général Java
    Réponses: 4
    Dernier message: 21/08/2013, 12h14
  4. [Avis] Les meilleurs programmes Java ?
    Par christopheJ dans le forum ImageJ
    Réponses: 69
    Dernier message: 07/10/2008, 01h12
  5. [Stratégie] Ant pour les tests en Java ?
    Par franckR dans le forum Tests et Performance
    Réponses: 5
    Dernier message: 08/03/2004, 09h38

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