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 :

Généricité, héritage et Reflexion/introspection


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    370
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Avril 2006
    Messages : 370
    Par défaut Généricité, héritage et Reflexion/introspection
    Bonjour,

    je rencontre un petit soucis Java autour de l'héritage, généricité et de l'utilisation des outils de réflexion/introspection java.

    Le problème se pose aussi bien avec l'utilsation d'une interface ou d'une classe mère pour la généricité. Voici le problème
    J'ai donc une classe générique (ou une interface ...)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public class GenericClass {
    }
    et des implémentation différentes de cette classe générique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class SpecifClass1 extends GenericClass {
    }
     
    public class SpecifClass2 extends GenericClass {
    }
     
    ...
    Pour un besoin particulier dans une factory, j'ai besoin d'instancier un nouvel objet spécifique en fonction d'un élément (ici une String passé en paramètre).
    Pour faire "élégant" et éviter une enorme imbrication de if,else if ... je voudrais créer une Map du type qui contiendrai de façon générique mes associations.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Map<String,Class<GenericClass>> assoStringClass ;
    que je remplis de la sorte a la construction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    assoStringClass = new HashMap<String,Class<GenericClass>> ;
    assoStringClass.put("chaine1",SpecifClass1.class) ;
    assoStringClass.put("chaine2",SpecifClass2.class) ;
    Seulement ici il me sort une erreur car pour lui Class<SpecifClass1> (donc issu de mon put) ou Class<SpecifClass2> ne peut pas être mis ds HashMap<String,Class<GenericClass>> malgrès le lien entre GenericClass et les specif class.

    L'idée étant ensuite d'instancier le bon Spécifique en fonction d'une égalité entre 2 String :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if(assoStringClass.containsKey(maChaineParam) {
         GenericClass = assoStringClass.get(maChaineParam).newInstance();
    Des idées pour faire fonctionner tout ça ?

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    280
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 280
    Par défaut
    Salut,
    Essayes avec ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Map<String,Class<? extends GenericClass>> assoStringClass ;
    ---
    Farid

  3. #3
    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,


    C'est normal car il n'y a pas de notion d'héritage dans les Generics tel qu'il existe pour les types standards, car cela peut entrainer beaucoup d'incohérence. Du coup il n'y a pas de transtypage sur les types Generics...

    Par exemple puisque Integer hérite de Number on peut faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Number number = new Integer();
    Par contre tu ne peux pas faire cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<Number> list = new ArrayList<Integer>(); // ERREUR
    Car sinon tu pourrais casser le typeage du List<Integer>, par exemple avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    list.add(new Double(0.0));
    // correct pour le compilateur , car on ajoute un Double dans une List<Number>
    // mais incorrect car on ajouterait en réalité un Double dans une List<Integer>


    Pour pallier à cela, on utilise la notion de wildcard qui permettent de se rapprocher du transtypage en limitant les fonctionnalité, ce qui interdit d'utiliser une méthode avec un type inconnu ou méconnu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    List<? extends Number> list = new ArrayList<Integer>(); // Correct
     
    list.add(new Double(0.0));	// ERREUR
    list.add(new Integer(0.0));	// ERREUR
    // => Comme on ne connait pas le type précis de la liste
    // on ne peut pas utiliser les méthodes qui attendent
    // un type paramétré en paramètre, même si on utilise le bon type
    // (le compilateur n'est pas censé le connaitre ;))
     
    // Par contre on peut utiliser les méthodes qui renvoient le
    // type paramétré (il sera vu alors comme un Number) :
    for (Number n : list) {
    	System.out.println(n);
    }


    Dans dans ton cas le problème vient du fait que Class<GenericClass> représente précisément le type de la classe GenericClass, mais pas ses sous-types.

    Tu dois utiliser Class<? extends GenericClass> pour autoriser les sous-types
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Map<String,Class<? extends GenericClass>> assoStringClass = new HashMap<String,Class<? extends GenericClass>>();
    a++

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    370
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Avril 2006
    Messages : 370
    Par défaut
    merci beaucoup, cela fait des années que je tournais sous Java 1.4 (merci le progrès) et en effet toutes ces notions de Generics, wildcard et cie remonte a bien longtemps.

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

Discussions similaires

  1. Introspection et Généricité
    Par LittleBean dans le forum Langage
    Réponses: 3
    Dernier message: 04/06/2009, 10h46
  2. Héritage, Généricité, Cast?!
    Par aroussi_sanaa dans le forum Général Java
    Réponses: 1
    Dernier message: 04/05/2009, 11h10
  3. Question de généricité et d'héritage
    Par fatypunk dans le forum Langage
    Réponses: 7
    Dernier message: 22/06/2008, 13h12
  4. Généricité et héritage
    Par TiteMarie dans le forum Langage
    Réponses: 3
    Dernier message: 27/05/2008, 12h17
  5. introspection & généricité
    Par xixi31 dans le forum Langage
    Réponses: 5
    Dernier message: 02/02/2006, 11h10

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