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 :

Generics et reflection


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 6
    Par défaut Generics et reflection
    Bonjour,
    Un problème que je n'arrive vraiment pas à résoudre, et qui semble pouvoir l'être d'après ce que j'ai pu lire sur la reflection des generics.

    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
     
    public class CompositeDeElement<E extends Composant> {
    	private static final long serialVersionUID = 1L;
    	private ArrayList<E> childs;
     
    	public void fromXML(SimpleXML xml) {
    		List<String> nodeNames = xml.getNodes();
     
    		if(nodeNames.size() != 0) {
    			String name = nodeNames.get(0);
    			List<SimpleXML> nodes = xml.getNodes(nodeNames.get(0));
    			for(SimpleXML node : nodes) {
    				E e = new E(node);
    				this.add(e);
    			}
    		}
    	}
    }
    Sauf que ... E e = new E(node);, forcément ça marche pas.
    J'utilise la clase de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public class Document extends CompositeDeElement<Page> {
    	private static final long serialVersionUID = 1L;
    }
    Si quelqu'un voyait comment faire ...

  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,

    Citation Envoyé par Iksaif
    Un problème que je n'arrive vraiment pas à résoudre, et qui semble pouvoir l'être d'après ce que j'ai pu lire sur la reflection des generics.
    Non : il est impossible d'instancier un objet de cette manière (new E()). Pour plus d'info : Les Generics ne sont pas des Templates comme les autres !


    En effet le type E est perdu à l'exécution, et doit donc être conservé manuellement, par 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public class CompositeDeElement<E extends Composant> {
    	private static final long serialVersionUID = 1L;
    	private final Class<E> type;
    	private ArrayList<E> childs;
     
    	public CompositeDeElement(Class<E> type) {
    		if (type==null) {
    			throw new NullPointerException("null type");
    		}
    		this.type = type;
    	}
     
    	private E newE(SimpleXML node) {
    		try {
    			return this.type.getConstructor(SimpleXML.class)
    				.newInstance(node);
    		} catch (Exception e) {
    			throw new RuntimeException("Instantiation error", e);
    		}
    	}
     
    	public void fromXML(SimpleXML xml) {
    		List<String> nodeNames = xml.getNodes();
     
    		if(nodeNames.size() != 0) {
    			String name = nodeNames.get(0);
    			List<SimpleXML> nodes = xml.getNodes(nodeNames.get(0));
    			for(SimpleXML node : nodes) {
    				E e = newE(node);
    				this.add(e);
    			}
    		}
    	}
     
     // ...
    }

    Que tu peux ensuite utiliser de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class Document extends CompositeDeElement<Page> {
    	private static final long serialVersionUID = 1L;
     
    	public Document() {
    		super(Page.class);
    	}
    }
    a++

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 6
    Par défaut
    Non : il est impossible d'instancier un objet de cette manière (new E()). Pour plus d'info : Les Generics ne sont pas des Templates comme les autres !
    Ouep, ça jvais plus ou moins compris, mais d'après ce que j'avais pu lire ici par exemple : http://www-128.ibm.com/developerwork...-cwt11085.html
    Je me disais, que y'avais sûrement moyen de bidouiller un peu..

    Bon, passer le type en paramètre, j'y avait pensé, mais je voulais éviter .. sauf que si j'ai pas le choix ..

    merci

  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 Iksaif
    Bon, passer le type en paramètre, j'y avait pensé, mais je voulais éviter .. sauf que si j'ai pas le choix ..
    Il y a un moyen de l'éviter, mais cela implique l'utilisation d'un type en dur lors de l'héritage.

    Par exemple lorsque tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public class Document extends CompositeDeElement<Page> {
    }
    Le type Page peut être retrouvé en utilisant getGenericSuperClass() et l'interface ParameterizedType.


    Tu pourrais le récupérer automatiquement de la manière suivante par 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
    26
    27
    	protected CompositeDeElement() {
    		Class<E> argClass = null;
    		Class c = getClass();
    		// On parcours tout les types
    		while (c!=null) {
    			// Si la classe parente est de type CompositeDeElement
    			if (c.getSuperclass()==CompositeDeElement.class) {
    				// On la récupère avec les infos des Generics
    				Type genericType = c.getGenericSuperclass();
    				if (genericType instanceof ParameterizedType) {
    					// On récupère le type parametré :
    					ParameterizedType paramType = (ParameterizedType) genericType;
    					Type argType = paramType.getActualTypeArguments()[0];
    					if (argType instanceof Class) {
    						argClass = (Class<E>) argType;
    					}
    					break;
    				}
    			}
    			c = c.getSuperclass();
    		}
    		this.type = argClass;
     
    		if (this.type==null) {
    			throw new NullPointerException("Unable to determine type");
    		}
    	}


    Par contre cela ne marchera pas lorsque tu fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public class Document<E extends Composant> extends CompositeDeElement<E> {
    }
    Car alors il n'y a aucun moyen de récupérer le type paramétré...

    a++

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 6
    Par défaut
    Merci, c'est ce que je recherchais =).
    Mais je viens de me rendre compte que sans rendre disponible la hérarchie entière, ça fait des trucs pas super beaux ... Et comme je débute en Java, on va pas tenter de faire des trucs trop complexe, autant rester dans le simple (et élégant, si possible)

Discussions similaires

  1. [Reflection] Probleme d'appel newInstance()
    Par SEMPERE Benjamin dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 17/06/2004, 13h15
  2. [Reflection] Exécuter une méthode donnée d'une classe
    Par schousso dans le forum API standards et tierces
    Réponses: 4
    Dernier message: 03/06/2004, 10h35
  3. [Reflection]Probleme d'InstantiationException
    Par guipom dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 23/05/2004, 23h28
  4. [Reflection][Bean] Appel d'une méthode dynamiquement
    Par eraim dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 28/04/2004, 11h07
  5. Reflections
    Par Laurent Gomila dans le forum DirectX
    Réponses: 4
    Dernier message: 25/07/2003, 14h42

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