lmarin Posté(e) le 28 octobre 2009 Partager Posté(e) le 28 octobre 2009 Bonjours à tous, J'ai une classe qui contient une liste d'objet dont le type est passer en paramétre générique de ma classe ( cf code ) public class MaListe<T> extends UneClasseAbstraite<T> { private List<T> listes; ... @Override public void maMethodeDeMaClasseAbstraite( T obj) { ... } } Je souhaiterais faire de l'introspection sur les objets contenus dans ma liste de Type "T", comment faire ? J'ai tenté de faire de taper sur du this.getClass().getTypeParameters() sans résultat. Merci ! Lien vers le commentaire Partager sur d’autres sites More sharing options...
Shtong Posté(e) le 28 octobre 2009 Partager Posté(e) le 28 octobre 2009 Il faut plutôt que tu récupère le type des instances génériques, cad par exemple listes.getClass() ou obj.getClass() dans ta méthode. Ou peut-être aussi en faisant T.class ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
fabien29200 Posté(e) le 28 octobre 2009 Partager Posté(e) le 28 octobre 2009 Le mot clé "this" représente l'objet en cours. Donc tout dépend de où tu veux introspecter. Mais si tu veux introspecter les objects d'une liste, il faut les récupérer un par un et faire un getClass() sur chaque objet. Lien vers le commentaire Partager sur d’autres sites More sharing options...
lmarin Posté(e) le 28 octobre 2009 Auteur Partager Posté(e) le 28 octobre 2009 Je souhaiterais introspecter depuis MaListe l'objet passé en paramètre, à sa voir T, hors T.getClass() n'existe pas :) La présence de la liste ici n'est la que pour l'exemple. Lien vers le commentaire Partager sur d’autres sites More sharing options...
fabien29200 Posté(e) le 28 octobre 2009 Partager Posté(e) le 28 octobre 2009 Quel objet en paramètre ? Tu veux dire dans maMethodeDeMaClasseAbstraite ? Si tu veux introspecter obj, alors tu dois faire obj.getClass() Après si tu commences à faire de l'instrospection dans une classe générique, demande toi bien si tu ne fais pas une erreur de conception. Car le but de la généricité est justement de ne pas faire cela. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Shtong Posté(e) le 28 octobre 2009 Partager Posté(e) le 28 octobre 2009 Je souhaiterais introspecter depuis MaListe l'objet passé en paramètre, à sa voir T, hors T.getClass() n'existe pas :) Bien sûr que non, mais il est possible que T.class existe (comme quand tu fais String.class, mais je n'en mettrai pas ma main à couper) Dans tous les cas, tu peux appeler getClass sur l'instance (et non la classe) de T que tu reçois en paramètre ! Lien vers le commentaire Partager sur d’autres sites More sharing options...
lmarin Posté(e) le 29 octobre 2009 Auteur Partager Posté(e) le 29 octobre 2009 Je souhaiterais faire de l'introspection dans le constructeur de la classe MaListe, sinon effectivement, je le fairais dans la méthode qui prends T en argument :) Et T.class n'existe pas. Lien vers le commentaire Partager sur d’autres sites More sharing options...
fabien29200 Posté(e) le 29 octobre 2009 Partager Posté(e) le 29 octobre 2009 Dans ce cas, tu n'as pas d'autre choix que de passer la classe en paramètre. public MaListe ( Class<T> theClass ) et introspecter dessus. Il faut bien se rappeler qu'il ne reste aucune référence aux classes génériques une fois le code compilé. Donc T.class n'a aucun sens puisque T sera transformé en Object une fois le travail du compilateur effectué. Maintenant, ce n'est pas une bonne pratique que d'introspecter. Il faut que ça reste une exception dans le code .... Lien vers le commentaire Partager sur d’autres sites More sharing options...
Shtong Posté(e) le 29 octobre 2009 Partager Posté(e) le 29 octobre 2009 Justement je pensais que si tu faisais T.class le compilo aurait remplacé par String.class si tu avais utilisé String et ça roulez... Mais bon ça fait tellement de temps que j'ai pas touché à Java, quand j'en faisait y avait pas encore de génériques Non mais sinon c'est vrai que si tu peux éviter d'utiliser l'introspection c'est mieux. En plus c'est méga lent en général. Lien vers le commentaire Partager sur d’autres sites More sharing options...
fabien29200 Posté(e) le 30 octobre 2009 Partager Posté(e) le 30 octobre 2009 Non non T est tout simplement mis de côté et inutilisé après pour que le code compilé puisse être exécuté avec une JVM 1.4. Les performances de l'introspection ont été largement améliorées dans les versions 1.5 et 1.6 mais il faut bien réfléchir à pourquoi on en a besoin car il y a bien souvent une solution autre (design pattern) qui permet d'arriver au même résultat de façon plus élégante. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 30 octobre 2009 Partager Posté(e) le 30 octobre 2009 Les types génériques existent uniquement dans le code source, pour permettre au compilateur de s'assurer que, par exemple, on ne place que des objets du type autorisé dans une collection. Le but étant d'éviter au maximum les ClassCastException lorsqu'on tente de récupérer les objets depuis ladite collection. Mais, pour des raisons de rétrocompatibilité avec la base de code existante (les applis en entreprise), le compilateur supprime toutes ces informations de typage : c'est ce qu'on appelle la phase de "type erasure". Au runtime, les types génériques n'existent donc plus. Ce que tu obtiens en appelant getTypeParameters(), c'est uniquement les noms des placeholders (le "T" de UneClasseAbstraite<T>). Lien vers le commentaire Partager sur d’autres sites More sharing options...
lmarin Posté(e) le 2 novembre 2009 Auteur Partager Posté(e) le 2 novembre 2009 Dans l'idée, je voudrais juste me faire un TableModel par défaut qui irait faire de l'introspection sur les objets métiers à afficher pour mettre les attributs publics dans les colonnes. L'objet métier étant passé a ma classe en générique est donc l'inspection sur l'objet générique. La seule solution que j'ai pu entre voir consiste a faire de l'introspection sur une méthode de ma classe qui prends en argument ou en retour un générique, et je peux pas dire que je trouve cette solution très glamour.... Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 3 novembre 2009 Partager Posté(e) le 3 novembre 2009 Tu peux me faire voir lse quelques classes concernées ? (ton tablemodel, la classe appelante...) Sur le forum ou en privé, comme tu veux. Lien vers le commentaire Partager sur d’autres sites More sharing options...
touftouf57 Posté(e) le 15 janvier 2010 Partager Posté(e) le 15 janvier 2010 Bonjour, justement je cherche à faire ça, c'est à dire, récupérer la class de T passé en argument de TableModelPerso(List<T> list). Ceci dans le but de faire de l'introspection pour les headers de ma JTable. public TableModelPerso(List<T> list) { super(); Object o = null; titres = new ArrayList<String>(); data = new Vector<Vector<Object>>(); o = list.get(0); Class oClass =o.getClass(); Field[] oFields = oClass.getDeclaredFields(); for (int i = 0; i < oFields.length; i++) { Field champs = oFields[i]; if (champs.isAnnotationPresent(TableHeader.class)) { Annotation tableHeaderAnnot = champs.getAnnotation(TableHeader.class); TableHeader header = (TableHeader) tableHeaderAnnot; while (titres.size() < header.index()) { titres.add(null); data.add(null); } titres.set(header.index() - 1, header.value());... Je précise que la classe TableHeader est une classe héritant de Annotation. Dans la classe T (que je cherche à obtenir) j'ai ajouté des annotations précisant le titre de la colonne ainsi que son index par défaut. Dans ce bout de code, la chose qui me dérange est que si list est vide et bien je me récupère une exception, et même si je la capte je ne peux pas faire d'introspection, donc j'aurais un tableau sans titres de colonne. Un petit éclaircissement, ou une autre façon d'aborder ceci, serait le bienvenue. Merci d'avance Lien vers le commentaire Partager sur d’autres sites More sharing options...
fabien29200 Posté(e) le 15 janvier 2010 Partager Posté(e) le 15 janvier 2010 Comme vu précédemment, tu passes la classe dans le constructeur : public TableModelPerso(List<T> list, Class<T> clazz) Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.