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

  1. #1
    Membre averti
    Avatar de rozwel
    Inscrit en
    mars 2002
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : mars 2002
    Messages : 324
    Points : 327
    Points
    327

    Par défaut Possibilité d'accéder au type générique en runtime

    Un collègue vient de me montrer un truc très bizarre dans un code qu'il a fait et ça m'intrigue beaucoup.
    Dans la certification que j'ai passé il n'y a pas très longtemps, ils insistaient bien sur le fait qu'aucune information sur les generics ne se retrouvait dans le bytecode compilé, et que par conséquent, on ne pouvait pas retrouver le type des éléments contenus dans une collection générique AU RUNTIME.

    Pourtant, si j'ai une classe du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public class MaClasse{
      public Collection<Truc> getTrucs(){}
    }
    Apparemment, j'arrive à savoir que getTrucs renvoie une collection de Truc's en faisant:
    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
    26
    27
    28
    29
     
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.Collection;
     
    class Truc {
    }
     
    class MaClasse {
        private Collection<Truc> trucs;
     
        public Collection<Truc> getTrucs() {
            return trucs;
        }
     
        public static void main(String[] args) throws NoSuchMethodException {
            Method getter = MaClasse.class.getMethod("getTrucs");
            Type type = getter.getGenericReturnType();
     
            if (type instanceof ParameterizedType) {
                Type genericType = ((ParameterizedType) type).getActualTypeArguments()[0];
                if (genericType instanceof Class) {
                    Class<?> contentClass = (Class<?>) genericType;
                    System.out.println(contentClass);
                }
            }
        }
    }
    Comment ça se fait? J'ai du rater un épisode.
    Sébastien ARBOGAST
    SCJP

  2. #2
    Membre averti
    Inscrit en
    juin 2003
    Messages
    292
    Détails du profil
    Informations forums :
    Inscription : juin 2003
    Messages : 292
    Points : 317
    Points
    317

    Par défaut

    oui c est bizarre, mais la recuperation de ces generiques ne se fait qu en reflection donc forcement ces informations sont quelque part dans le bytecode, mais ou et comment?

  3. #3
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 930
    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 930
    Points : 22 979
    Points
    22 979
    Billets dans le blog
    1

    Par défaut

    Salut,

    Citation Envoyé par rozwel Voir le message
    Comment ça se fait? J'ai du rater un épisode.
    C'est tout à fait normal !

    Les fichiers *.class compilés contiennent bien des informations sur les Generics, notamment afin de permettre aux compilateurs de les utiliser sans qu'il ne leurs soit nécessaire d'avoir leurs codes sources...

    Mais tu ne peux avoir que les informations relatives au type et non pas celles qui sont lié à une instance.

    Par exemple si tu as :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public class MaClasse {
     
        private Collection<String> collection;
     
    }
    Tu pourras récupérer Collection<String> via l'API de reflection et la méthode getGenericType() du type Field. Mais en fait ici tu n'as pas vraiment de code paramétré car il s'agit d'un type fixe.


    Par contre si tu as :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public class MaClasse<T> {
     
        private Collection<T> collection;
     
    }
    Tu récupèreras simplement Collection<T>. En fait c'est tout à fait normal car l'API de reflection fonctionne sur le type de la classe et non pas sur une instance particulière. Ainsi c'est l'information lié à l'instance qui n'est pas stocké en mémoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Object o = new Collection<String>()
    Il est impossible de récupérer Collection<String> via l'API de réflection...


    Je ne sais pas si je suis clair...

    a++

  4. #4
    Membre averti
    Avatar de rozwel
    Inscrit en
    mars 2002
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : mars 2002
    Messages : 324
    Points : 327
    Points
    327

    Par défaut

    Tu es parfaitement clair! Voilà qui éclaire ma lanterne. Ca m'apprendra à modérer mes propos quand un collègue vient me demander si c'est possible...
    Merci beaucoup.
    Sébastien ARBOGAST
    SCJP

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

Discussions similaires

  1. Type générique paramétré ?
    Par Lebbihi dans le forum Langage
    Réponses: 2
    Dernier message: 15/03/2007, 09h58
  2. [Framework] IOC - Type générique
    Par seawolfm dans le forum Spring
    Réponses: 1
    Dernier message: 06/02/2007, 18h17
  3. Réponses: 12
    Dernier message: 23/09/2006, 12h12
  4. [Generics] Accéder au type du type paramétré
    Par Beuss dans le forum Langage
    Réponses: 2
    Dernier message: 18/09/2006, 16h09
  5. y a-t-il un support de types génériques pour python ?
    Par silverhawk.os dans le forum Général Python
    Réponses: 15
    Dernier message: 24/03/2006, 18h23

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