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 :

Nom de la classe générique


Sujet :

Langage Java

  1. #1
    Membre confirmé Avatar de kha_yassine
    Inscrit en
    Juin 2007
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 126
    Par défaut Nom de la classe générique
    Salut tout le monde,

    Je me demande si je peux savoir le nom de la classe générique lors de l'exécution de mon programme,

    Je m'explique :

    Étant donné la classe A suivante :

    class A<T>{
    public String getNom(T t){
    return nomDeLaClasseT(T);
    }
    }

    et merci d'avance

  2. #2
    Membre expérimenté
    Homme Profil pro
    Consultant PLM
    Inscrit en
    Août 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant PLM

    Informations forums :
    Inscription : Août 2007
    Messages : 203
    Par défaut
    ?

  3. #3
    Membre confirmé Avatar de kha_yassine
    Inscrit en
    Juin 2007
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 126
    Par défaut
    Pour le T.getClass();

    Ca donne :

    Cannot make a static reference to the non-static method getClass() from the type Object

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    On peut pas, non. Au Runtime, les génériques ça n'existe plus, donc cette information n'existe pas.

    Il est possible, si nécessaire, de demander un objet Class<T> en paramètre du constructeur de ta classe, ce qui du coup permet de retenir la classe utilisée et de s'en servir. Mais l'intérêt, bon...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre expérimenté
    Homme Profil pro
    Consultant PLM
    Inscrit en
    Août 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant PLM

    Informations forums :
    Inscription : Août 2007
    Messages : 203
    Par défaut
    Moi pas comprendre quelque chose ?!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class A<T>{
    	public String getNom(T t){
    		return t.getClass().getName();
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class Main {
    	public static void main(String[] args) {
    		A<String> a = new A<String>();
    		System.out.println(a.getNom("toto"));
     
    		A<Integer> b = new A<Integer>();
    		System.out.println(b.getNom(Integer.valueOf(1)));
    	}
    }
    Ca me donne :
    java.lang.String
    java.lang.Integer
    C'était pas ça l'idée de départ ?!

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Moi je croyais qu'on n'avait pas sous la main une instance de T. On peut toujours faire getClass() sur une instance.

    Toutefois, attention, t n'est pas forcément de classe T. Ça peut être une sous-classe.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre expérimenté
    Homme Profil pro
    Consultant PLM
    Inscrit en
    Août 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant PLM

    Informations forums :
    Inscription : Août 2007
    Messages : 203
    Par défaut
    Ah oui, en effet, si l'objectif est d'avoir T, ça ne me semble pas possible ...

  8. #8
    Membre confirmé Avatar de kha_yassine
    Inscrit en
    Juin 2007
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 126
    Par défaut
    Merci beaucoup pour vos réponses

    Je vais voir si on ne peut pas travailler autrement (sans tenter de récupérer le nom de la classe T)

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Si je peux apporter une précision. Il faut bien être conscient que la classe générique A est compilée par le compilateur comme si T est un Object.

    Le generic sont traités par l'appelant, pas par l'appelé, contrairement au C++.

    Ainsi, une méthode public void do(T t), aura pour signature do(Object)
    Donc toute tentative depuis la classe de savoir comment on a été typé à l'instanciation est vouée à l'échec, cette information est inexistante en dehors de l'appelant. Donc si l'appelé a besoin de connaitre le type concret, il faudra lui passer en paramètre de la méthode (via un paramètre Class<T> par exemple)

  10. #10
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Dernière précision : si tu as effectivement implémenté la classe, alors le type peut être connu.

    Typiquement, quand tu crées une classe utilitaire destinée à être implémentée N fois, et que tu ne veux pas ré-écrire dans chaque classe une méthode qui retourne le type implémenté, tu peux utiliser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0].getClass().getName()
    En faisant attention au nombre de types d'arguments déclarés, à ce que ça passe par une classe héritée ou une interface, etc.

  11. #11
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 155
    Par défaut
    Citation Envoyé par Rei Ichido Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0].getClass().getName()
    En faisant attention au nombre de types d'arguments déclarés, à ce que ça passe par une classe héritée ou une interface, etc.
    Je n'aime pas trop cette fonctionnalité qui peut bugguer dès qu'une sous-classe ajoute ou change l'ordre des types.
    Si l'on utilise cette méthode, il vaut mieux mettre la classe en final, histoire de s’éviter ces problèmes.
    Ou alors utiliser une variable Class<T> comme l'a préconisé tchize_.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Ce code est de la bidouille qui va sauter à la première utilisation de l'héritage. Exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class A<T> {
        protected Class<T> getType(){
            ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0].getClass();
        }
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class B extends A<String> {
     //marchera
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class C extends B {
     // ne marche plus
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class D<U,V> extends A<U> {
     // ne marchera pas
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private A<Integer> a = new A<Integer>(); // ne marchera pas
    A part pour les deux derniers points, on peux améliorer le code de getType pour qu'il soit un peu plus souple et determine correctement le type concerné. Mais dans les deux derniers cas, impossible.

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 117
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Ce code est de la bidouille qui va sauter à la première utilisation de l'héritage. Exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class A<T> {
        protected Class<T> getType(){
            ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0].getClass();
        }
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class B extends A<String> {
     //marchera
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class C extends B {
     // ne marche plus
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class D<U,V> extends A<U> {
     // ne marchera pas
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private A<Integer> a = new A<Integer>(); // ne marchera pas
    A part pour les deux derniers points, on peux améliorer le code de getType pour qu'il soit un peu plus souple et determine correctement le type concerné. Mais dans les deux derniers cas, impossible.
    Effectivement en cas d'héritage ça peut être instable. En fait pour que ça marche il faut que ta classe hérite elle même d'une super classe qui sera paramétrée par ton type. Dans ce cas tu peux faire un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    	public static Type[] getTypeArguments(Class<?> clazz) {
    		if (null == clazz) {
    			return null;
    		}
    		Type type = clazz.getGenericSuperclass();
    		while ((null != type) && (!(type instanceof ParameterizedType))) {
    			type = ((Class) type).getGenericSuperclass();
    		}
    		return ((null != type) ? ((ParameterizedType) type)
    				.getActualTypeArguments() : null);
    	}

  14. #14
    Membre confirmé Avatar de kha_yassine
    Inscrit en
    Juin 2007
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 126
    Par défaut
    Oui ca marche bien

    Merci beaucoup

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 12/04/2007, 17h08
  2. Réponses: 4
    Dernier message: 09/11/2006, 16h47
  3. [POO] Instancier un objet avec le nom de la classe
    Par shinchun dans le forum Langage
    Réponses: 4
    Dernier message: 08/06/2006, 13h44
  4. [C#][ADO] Classe Générique ADO
    Par tscoops dans le forum Accès aux données
    Réponses: 2
    Dernier message: 15/11/2005, 14h21
  5. [Generics] Classe générique
    Par norkius dans le forum Langage
    Réponses: 4
    Dernier message: 29/10/2004, 15h57

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