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érics] Méthode de cast


Sujet :

Langage Java

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Points : 199
    Points
    199
    Par défaut [Générics] Méthode de cast
    Bonjour,

    Dans une classe, j'ai une HashMap<String,Object>. Pour récupérer les valeurs de cette map, j'ai plusieurs méthodes (extrait) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public Object getValeur(String nom){
     return map.get(nom);
    }
    public String getString(String nom) {
     return (String) map.get(Nom);
    }
    public Date getDate(String nom) {
     return (Date) map.get(nom);
    }
    Je voudrais savoir si je peux réunir ces méthodes en utilisant un "cast" en générique, du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    @SuppressWarnings("unchecked")
    public K getObjet(String nom) {
     Object valeur = map.get(Nom);
     return valeur instanceof K ? (K) valeur : null;
    }
    J'avais lu dans un post, une méthode correspondant à ce que je cherche, pour convertir un objet non typé en objet paramétré, mais je ne retrouve plus le code :/
    Pensez au tag quand votre problème est réglé !

  2. #2
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 562
    Points : 15 493
    Points
    15 493
    Par défaut
    Visiblement la map peut contenir des objets de type différents. Donc je ne vois pas vraiment ce que tu souhaites tirer de l'utilisation des génériques dans ce cas.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Points : 199
    Points
    199
    Par défaut
    De simplifier le code : Au lieu d'avoir n méthode pour "précaster" mes objets (getDate, getNumber, getString, ...), je n'en aurais plus qu'une (K getObjet).
    Ainsi, si j'ajoute un nouvel objet, je n'ai pas besoin de rajouter une méthode "getXXXX" dans toutes mes classes utilisant ce système.

    J'avais lu ce genre de méthode pour convertir une List non typée en List typée, évitant d'avoir des @suppressWarning trop fréquent.
    Pensez au tag quand votre problème est réglé !

  4. #4
    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
    on ne peux pas tester la valeur à l'exécution d'une instance par rapport à un type générique, ni faire de typecasting vers les type générique.


    Quand tu écrit

    c'est exactement le meme code binaire qui est généré que pour
    L'information sur les types des générique n'est plus présente à l'exécution, elle ne sert qu'au compilateurs

  5. #5
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Il faut impérativement spécifier le type à un moment donné.
    Le problème étant que le typage Generics ne permet pas de connaitre le type réel utilisé au final...

    Tu pourrais faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	@SuppressWarnings("unchecked")
    	public <K> K getObject(String key) {
    		return (K) map.get(key);
    	}
    Mais si la compilation se passe bien, tu n'es pas protégé des ClassCastException... mais le pire c'est que l'exception ne survient pas dans la méthode mais en dehors lors de l'affectation !


    La solution serait de passer le type souhaité en paramètre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	public <K> K getObject(Class<K> clazz, String key) {
    		Object object = map.get(key);
    		if (clazz.isInstance(object)) {
    			return clazz.cast(object);
    		}
    		return null;
    	}
    Du coup la vérification peut avoir lieu à l'intérieur de la méthode mais c'est un peu plus "lourd" à l'utilisation

    a++

  6. #6
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 562
    Points : 15 493
    Points
    15 493
    Par défaut
    De simplifier le code : Au lieu d'avoir n méthode pour "précaster" mes objets (getDate, getNumber, getString, ...), je n'en aurais plus qu'une (K getObjet).
    Ainsi, si j'ajoute un nouvel objet, je n'ai pas besoin de rajouter une méthode "getXXXX" dans toutes mes classes utilisant ce système.
    Les génerics ne sont pas un solution à ça: ton K devra être défini a la création de la classe qui l'utilise, donc ton getObject() retournera toujours le même type d'objet pour chaque instance de la classe.
    Tu ne pourrais donc plus stoker des objets de type différents dans cette map.

  7. #7
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 562
    Points : 15 493
    Points
    15 493
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Mais si la compilation se passe bien, tu n'es pas protégé des ClassCastException... mais le pire c'est que l'exception ne survient pas dans la méthode mais en dehors lors de l'affectation !
    On ne pourrait pas faire?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @SuppressWarnings("unchecked")
    public <K> K getObject(String key) {
        try {
            K object = (K) map.get(key);
            return object;
        } catch (ClassCastException ex) {
            return null;
        }
    }

  8. #8
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Uther Voir le message
    On ne pourrait pas faire?
    Non car à l'intérieur de la méthode le cast est purement logique et ne sert qu'à la compilation...

    Grosso-modo ce code revient à faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public Object getObject(String key) {
        try {
            Object object = (Object) map.get(key);
            return object;
        } catch (ClassCastException ex) {
            return null;
        }
    }
    Bref il n'y a pas de cast en réalité. Il est déplacé à l'appel de la méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String str = getObject("key");
    Qui devient donc implicitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String str = (String) getObject("key");
    Bref l'exception ne pourra pas être intercepter à l'intérieur de la méthode

    a++

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Points : 199
    Points
    199
    Par défaut
    D'accord, merci pour vos réponses, ça me convient parfaitement
    Pensez au tag quand votre problème est réglé !

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

Discussions similaires

  1. Cast généric T et héritage
    Par lead8209 dans le forum C#
    Réponses: 3
    Dernier message: 22/01/2015, 14h47
  2. Appel de méthode par adresse, liaison tardive ou dynamic cast
    Par weabow dans le forum Général Java
    Réponses: 6
    Dernier message: 22/05/2013, 13h40
  3. cast et surcharge d'une méthode
    Par fenrir22 dans le forum Débuter avec Java
    Réponses: 5
    Dernier message: 19/04/2011, 13h32
  4. Tableau de généric en retour de méthodes
    Par lvr dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 07/12/2009, 21h27
  5. Méthode de compression : cast sensible
    Par sperca dans le forum Débuter
    Réponses: 2
    Dernier message: 12/03/2009, 13h52

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