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é et .class


Sujet :

Langage Java

  1. #1
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2005
    Messages
    97
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2005
    Messages : 97
    Points : 78
    Points
    78
    Par défaut Généricité et .class
    Bonjour,

    Je bosse actuellement sur un projet J2EE et je voudrais écrire une classe générique pour les DAO.

    Voici le code que je pensais pouvoir écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public abstract class Dao<T> {
     
    public void getObjetById (Session s , Integer id)
    {
     T result = s.get(T.class,id);	
    }	
    }
    Je ne comprends pas pourquoi ce code ne compile pas.

    Auriez vous une solution à mon problème?

    Merci
    Le Principe de Peter : « Avec le temps, tout poste sera occupé par un incompétent incapable d'en assumer la responsabilité. »

  2. #2
    Membre confirmé Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Points : 493
    Points
    493
    Par défaut
    Les types génériques sont perdus lors de l'exécution, il n'est donc pas possible d'obtenir les infos de type T.class ou new T(). Ecrire un DAO avec les génériques java de cette manière ne me semble pas possible, même si je trouve ça dommage dans ce cas, ou la cast va perdurer.

  3. #3
    Membre averti
    Avatar de Mik ArBer
    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Avril 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2007
    Messages : 36
    Points : 334
    Points
    334
    Par défaut
    T n'existe pas au "run-time", donc le compilateur anticipe les problèmes et n'accepte pas tu cherches à récupérer son type.

    Je ne sais pas si cela convient à ton besoin, mais une des solutions les plus simples et de passer en paramètres le type de classe. J'ai aussi interprété que ta méthode getObjectById ramène une instance de type T.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public abstract class Dao<T> {
     
    	public  T getObjetById(Session s, Integer id, Class<T> type) {
     
    		T result = s.get(type , id);
     
    		return result;
    	}
    }
    A+

    Mik

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


    Comme le type paramétré est perdu à l'exécution, la solution est de le stocker 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
    public abstract class Dao<T> {
     
    	private final Class<T> type;
     
    	public Dao(Class<T> type) {
    		this.type = type;
    		if (this.type==null) {
    			throw new IllegalArgumentException("null type");
    		}
    	}
     
    	public void getObjetById (Session s , Integer id) {
    		T result = s.get(this.type, id);	
    	}	
    }

    A lire sur le blog sur ce sujet : Les Generics ne sont pas des Templates comme les autres !

    a++

    [edit] grillé

  5. #5
    Membre confirmé Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Points : 493
    Points
    493
    Par défaut
    L'ennui de cette approche c'est de devoir passer le type à chaque appel du DAO. Même si ça marche, je préfère garder des cast avec un DAO non generic-ready

    adiGuba, dans exemple que tu donnes, il ne serait pas possible selon moi de profiter du type paramétré comme valeur de retour de la méthode getObjectById. C'est bien ça ?

  6. #6
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Dans l'ensemble, lorsque l'objet vient de nulle part, comme c'est souvent le cas avec les DAO, je pense que l'ancienne forme, par les casts, est la meilleure.

    Les génériques exigent une logique complète dans la définition des types, et n'admettent pas qu'un objet x, y ou z devienne un T, S ou P sans warning ; et, s'il faut protéger le warning, autant utiliser les casts classiques directement, il me semble.

    Voici toutefois un exemple - inapplicable dans le contexte d'une DAO - où le code ne stipule ni type générique ni cast dans l'activation, seulement dans sa déclaration :
    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
     
    // une méthode quelque part...
    public static void main(String[] args) 
    {
      DAO<Date> daodate;
     
      // Plus besoin de répéter le type générique Date !
      daodate = DAO.nouv();
    }
     
    // le type générique, parfaitement classique
    // --------------------
    public class DAO<T>
      {
        private T objt;
     
        public T getObj(int id)
        {
          return objt;
        }
     
        public void setObj(T obj)
        {
          objt = obj;
        }
     
        // L'ASTUCE : une méthode statique de création générique
        public static <P> DAO<P> nouv()
        {
          return new DAO<P>();
        }    
      }
    J'utilise ici la notion d'inférence (What is type argument inference?). C'est une notion pratique, mais elle ne dispense pas d'avoir à préciser le type générique dans le code, et elle ne permet pas de le découvrir à l'exécution.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

Discussions similaires

  1. Classe pour la création d'un graphe xy
    Par Bob dans le forum MFC
    Réponses: 24
    Dernier message: 03/12/2009, 17h20
  2. Généricité et création de classes dynamiques
    Par virulent dans le forum Langage
    Réponses: 4
    Dernier message: 11/09/2009, 09h28
  3. Classe intervalle C++ avec généricité
    Par sanskrit76 dans le forum Débuter
    Réponses: 3
    Dernier message: 24/04/2009, 14h08
  4. Généricité en Java (classe avec paramètre)
    Par epcilone059 dans le forum Langage
    Réponses: 1
    Dernier message: 27/03/2009, 12h05
  5. Réponses: 31
    Dernier message: 30/03/2006, 16h57

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