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 :

Java et Generic


Sujet :

Langage Java

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2017
    Messages : 6
    Points : 3
    Points
    3
    Par défaut Java et Generic
    Salut à tous,

    Dans le cadre d'un projet assez complexe, je dois utiliser une Map avec comme clé une classe et comme valeur une liste d'objet d'instance de cette même classe.

    J'ai simplifié le code au maximum et j'arrive au code suivant:
    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
     
    public class Test {
    	private class BaseObject {
     
    	}
     
    	private class MyMap<T extends BaseObject> extends HashMap<Class<T>, List<T>> {
    		private static final long serialVersionUID = 1L;
    	}
     
    	private MyMap<? extends BaseObject> map;
     
    	public <T extends BaseObject> void put(Class<T> clazz, List<T> l) {
    		map.put(clazz, l);
    	}
     
    	public <T extends BaseObject> List<T> get(Class<T> clazz) {
    		return map.get(clazz);
    	}
    }
    Ca ne compile pas

    Bien-sûre je ne peux pas rendre la classe Test generic parce que je ne connais pas à l'avance le nombre de clé possible.

    Pour m'en sortir j'utilise le code suivant:
    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
     
    public class Test2 {
    	private class BaseObject {
     
    	}
     
    	private Map<Class<? extends BaseObject>, List<? extends BaseObject>> map;
     
    	public <T extends BaseObject> void put(Class<T> clazz, List<T> l) {
    		map.put(clazz, l);
    	}
     
    	public <T extends BaseObject> List<T> get(Class<T> clazz) {
    		return (List<T>) map.get(clazz);
    	}
    }
    Mais je trouve ça dommage de passer par un transtypage, et je suis à peu près sûre qu'il y a une solution plus propre, vous avez pas une idée ?

    Merci

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    Hello,

    Citation Envoyé par clebail Voir le message
    Mais je trouve ça dommage de passer par un transtypage, et je suis à peu près sûre qu'il y a une solution plus propre, vous avez pas une idée ?
    Hélas non.

    Ta classe fait bien son travail en faisant le cast elle-même pour que les appelants n'aient pas besoin de le faire. Mais, il est obligatoire, parce que le compilateur ne peut pas assurer que ton code respecte le typage.
    Ton code respecte bel et bien le typage : il s'assure que la map ne peut se faire insérer que des listes qui correspondent à la classe donnée. De ce côté-là, c'est bon.

    Mais c'est parce que le comportement de ton code est bon. Ça, le compilateur ne peut pas le savoir. C'est toi, développeur qui comprend ce que fait le code, qui le sait. Comme le compilateur ne peut pas savoir que le typage est respecté, tu es obligé de lui dire que si, c'est bien le cas et il doit te faire confiance. Avec le cast en question.

    Ta Map contient des listes de différents types, c'est comme ça, c'est à ça qu'elle sert. Le compilateur ne peut donc pas vérifier que les listes sont d'un type plus ou moins précis en fonction de la clé utilisée pour récupérer la liste. C'est toi seul qui le peux.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Il n'y a pas moyen de préciser au compilateur qu'il y a un lien entre la clé et la valeur. Tu va être obligé de cacher ça dans des méthodes avec des cast et des suppreswarning. D'ailleurs si ces suppresswarning sont là, c'est justement pour ce genre de cas. Quand le code s'assure de quelque chose dont le compilateur ne peut pas s'assurer. Le tout pour faire propre, c'est de limiter ça à ces méthode. Tu aura toujours le problème dès que tu va piocher dans un pool généraliste (ici hashmap) pour ramener vers un type lié à l'appel.

Discussions similaires

  1. Stéréotype List et generics java
    Par ptit-lu dans le forum BOUML
    Réponses: 4
    Dernier message: 30/07/2007, 11h11
  2. List Generics en Java & Reverse
    Par pomauguet dans le forum BOUML
    Réponses: 5
    Dernier message: 10/05/2007, 20h01
  3. Generic et java 1.6
    Par guis14 dans le forum Langage
    Réponses: 1
    Dernier message: 24/04/2007, 16h57
  4. [JAVA 5.0] Generics - Cast et creation d'objets
    Par bourbaki2003 dans le forum Langage
    Réponses: 12
    Dernier message: 14/03/2007, 16h34
  5. Generics et héritage avec Java 5.0 Tiger
    Par euyeusu dans le forum Langage
    Réponses: 3
    Dernier message: 17/01/2007, 12h41

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