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 :

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


Sujet :

Langage Java

  1. #1
    Membre averti
    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
    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
    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++
    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  4. #4
    Membre averti
    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

###raw>template_hook.ano_emploi###