Posté(e) le 28 octobre 200915 a 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 !
Posté(e) le 28 octobre 200915 a 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 ?
Posté(e) le 28 octobre 200915 a 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.
Posté(e) le 28 octobre 200915 a Auteur 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.
Posté(e) le 28 octobre 200915 a 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.
Posté(e) le 28 octobre 200915 a 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 !
Posté(e) le 29 octobre 200915 a Auteur 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.
Posté(e) le 29 octobre 200915 a 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 ....
Posté(e) le 29 octobre 200915 a 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.
Posté(e) le 30 octobre 200915 a 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.
Posté(e) le 30 octobre 200915 a 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>).
Posté(e) le 2 novembre 200915 a Auteur 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....
Posté(e) le 3 novembre 200915 a Tu peux me faire voir lse quelques classes concernées ? (ton tablemodel, la classe appelante...) Sur le forum ou en privé, comme tu veux.
Posté(e) le 15 janvier 201015 a 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
Posté(e) le 15 janvier 201015 a Comme vu précédemment, tu passes la classe dans le constructeur : public TableModelPerso(List<T> list, Class<T> clazz)
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.