Précédent   Forum des professionnels en informatique > Java > Général Java > Langage
Langage Forum d'entraide sur le langage Java et autres langages pour la JVM : syntaxe, POO, conventions, API standard. Avant de poster -> FAQ Java
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 31/10/2007, 16h56   #1
Membre actif
 
Avatar de rozwel
 
Inscription : mars 2002
Messages : 324
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 324
Points : 165
Points : 165
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 :
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 :
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
rozwel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/10/2007, 17h15   #2
Membre confirmé
 
Inscription : juin 2003
Messages : 292
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 292
Points : 269
Points : 269
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?
jhaythem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/10/2007, 17h20   #3
Rédacteur/Modérateur
 
Avatar de adiGuba
 
Homme
Développeur Java/Web
Inscription : avril 2002
Messages : 12 460
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Corse (Corse)

Informations professionnelles :
Activité : Développeur Java/Web
Secteur : Transports

Informations forums :
Inscription : avril 2002
Messages : 12 460
Points : 19 447
Points : 19 447
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 :
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 :
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 :
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++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java Présentation de Java SE 7 (commentaires)
adiGuba est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/10/2007, 20h25   #4
Membre actif
 
Avatar de rozwel
 
Inscription : mars 2002
Messages : 324
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 324
Points : 165
Points : 165
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
rozwel est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h00.


 
 
 
 
Partenaires

Hébergement Web