Methode toString() générique, introspection.

Methode toString() générique, introspection. - Java - Programmation

Marsh Posté le 08-10-2005 à 18:40:47    

Salut,
 
   Voila j'ai une classe BebeteAbstraite et une classe fille BebeteStupide, mon but est de faire une methode toString() générique dans la classe BebeteAbstraite qui affiche le nom des attributs et leur valeur, mais sans en connaître le nombre ni le type à l'avance.
 

Code :
  1. public abstract class BebeteAbstraite {
  2.    
  3.     int x, y;                 // position à l'écran
  4.     int vitesseCourante;      // vitesse en pixels par second
  5.     float directionCourante;  // en radians [0 - 2 PI[
  6.     Color couleur;            // Couleur de remplissage
  7.     ChampDeBebetes champ;     // Le champ
  8.     static final int TAILLEGRAPHIQUE = 10;
  9.     ...
  10.    
  11.       /* Methode toString generique */
  12.     public String toString() {
  13.         String res = "" + this.getClass().getCanonicalName() +
  14.                 "Noms des attributs : \n";
  15.         Class cl = this.getClass();                     
  16.         Field[] f = cl.getFields();
  17.         int mod;
  18.         for(int i=0; i<f.length ; i++){
  19.             mod = f[i].getModifiers();
  20.             res = res + Modifier.toString(mod);
  21.             res = res + " " + f[i].getDeclaringClass().getCanonicalName() + " " +
  22.                     f[i].getName() + ";\n";
  23.         }       
  24.         return res;
  25.     }
  26. }


 
A la compilation pas de probleme mais a l'execution j'ai tout mon IDE qui se bloque.
Donc je me suis dis que c'est normal car je suis dans une classe abstraite et qu'elle ne sera jamais instancié ...
 
J'ai remis cette methode dans la classe BebeteStupide et je l'ai viré de la classe abstraite.
 
Mais avec cet appel ça foire toujours et je pige pas trop pourquoi ...
 

Code :
  1. public class TestBebetes extends Frame {
  2.     ...
  3.     public static void main(String args[]) {
  4.         java.awt.Color c = new java.awt.Color(15);
  5.         ChampDeBebetes champ = new ChampDeBebetes(640,480);
  6.         BebeteStupide bet;
  7.         bet = new BebeteStupide(champ, 20, 20, 2, 30, c);
  8.         try {
  9.             System.out.println("" + bet.toString());
  10.            
  11.         } catch(Exception e) {
  12.             System.out.println("Classe non trouvée." );
  13.            
  14.             //new TestBebetes ().show ();
  15.         }
  16.     }
  17. }


 
Quelqu'un a t'il une idée svp ?


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 08-10-2005 à 18:40:47   

Reply

Marsh Posté le 08-10-2005 à 18:47:39    

En gros, des que je met  

Code :
  1. Class cl = this.getClass();


ca m'exlose a la figure.


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 08-10-2005 à 19:01:53    

Pq te casser la tête à réinventer la roue ? [:pingouino]
 
Fais une recherche du côté de Jakarta Commons, ou encore du côté des plugins Eclipse.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 08-10-2005 à 19:06:43    

Ouais mais c'est dans le cadre de mon tp donc a mon avis les plugin eclipse et autres c'est mort.


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 08-10-2005 à 19:17:46    

Chronoklazm a écrit :

Ouais mais c'est dans le cadre de mon tp donc a mon avis les plugin eclipse et autres c'est mort.


Quoi, tu dois ré-écrire un toString générique ??? C'est bien ça ?    [:pingouino]


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 08-10-2005 à 19:21:46    

Oui enfin pas un truc universel non-plus ..
 
 
 

Exercice 2 : une méthode toString générique
 
Ecrivez, dans la classe BebeteAbstraite du précédent projet, une méthode :
 
public String toString() {...}
 
...qui affiche le nom des attributs et leur valeur, mais sans en connaître le nombre ni le type à l'avance.
 
N'essayez pas de voir les attributs hérités dans un premier temps. En effet, la méthode getDeclaredFields() de la classe Class ne retourne que les attributs locaux.
 
Pour tester la méthode, faites par exemple afficher régulièrement les caractéristiques d'une bébête du simulateur sur la sortie standard (prenez par exemple la première bébête dans le moteur de simulation du ChampDeBebetes).  


Message édité par Chronoklazm le 08-10-2005 à 19:22:20

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 08-10-2005 à 19:30:19    

Quelle idée. [:pingouino]
 
Et quel est le message d'erreur ?


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 08-10-2005 à 19:33:42    

Bein le probleme c'est qu'il n'y en a pas. Just j'ai mon NetBeans qui se bloque pendant le build.


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 08-10-2005 à 20:19:13    

Chronoklazm a écrit :

Bein le probleme c'est qu'il n'y en a pas.


Merci d'avoir posté. C'est vendredi, ou quoi ?   [:pingouino]  
 

Chronoklazm a écrit :

Just j'ai mon NetBeans qui se bloque pendant le build.


Jamais vu ça avec Eclipse ou IntelliJ. Assez déroutant. Compile en dehors, pour voir si ça passe ou pas. En essayant de conserver le même CLASSPATH et de bien pointer vers le même JDK. Assez zarbi, ton histoire.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 09-10-2005 à 15:44:20    

sircam a écrit :

Merci d'avoir posté. C'est vendredi, ou quoi ?   [:pingouino]  


 
Tu peux decoder stp.
 
J'ai remarqué que  
 

Code :
  1. Class cl = this.getClass();                     
  2. Field[] f = cl.getFields();


 
Le tableau f est de taille 0 ... que je le recupere de getDeclaredFields() ou getFields() c'est pareil.


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 09-10-2005 à 15:44:20   

Reply

Marsh Posté le 09-10-2005 à 15:55:42    

Et j'ai recompilé à la main ca fait toujours pareil ... un blocage sans aucun message d'erreur.


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 09-10-2005 à 16:19:37    

Citation :

Tu peux decoder stp.


 
C'était à propos de :
 

Citation :

Bein le probleme c'est qu'il n'y en a pas.


 
Passons, c'est sans importance. [:pingouino]
 
Il convient d'être un peu plus rigoureux dans ce que tu dis ou fais :
 
1°- Tu dis que ça "explose" sur Class cl = this.getClass() pour ensuite parler de Field[] f = cl.getFields().
 
Si ça ne compile pas, comment peux-tu savoir que la taille de f est zéro ?
 
Car tu as bien dit :
 

Citation :

Just j'ai mon NetBeans qui se bloque pendant le build.


 
On parlait donc bien de compiler.
 
2°- Suite à quoi je te demande de compiler/exécuter tout cela en dehors de ton IDE : as-tu fait cela ???
 

Citation :

ca fait toujours pareil

On dirait que oui, mais alors la première partie de ton post ne correspond pas à ce qui se passe sur ton écran...
 
Si ça bloque à l'exécution ou à la compilation, comment peux-tu affirmer que f est de taille 0 ???
 
 
=> Tout cela manque de clarté et de rigueur ! :o


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 09-10-2005 à 16:57:21    

Citation :

On parlait donc bien de compiler.


 
Non car dans mon premier post, que tu as certainement lu, je dis la phrase suivante :
 

Citation :

A la compilation pas de probleme mais a l'execution j'ai tout mon IDE qui se bloque.


 
Mais c'est vrai ... je manque certainement de rigueur.
 

Citation :

Si ça bloque à l'exécution ou à la compilation, comment peux-tu affirmer que f est de taille 0 ???


 
Voila ce qui se passe :
 
- J'ai le code suivant dans la classe BebeteAbstraite qui est abstract bien entendu :
 

Code :
  1. public String toString(){
  2.         String res =
  3.                 "Noms des attributs : \n";
  4.             Class cl = this.getClass();           
  5.             res = res + "" + this.getClass().getCanonicalName();                               
  6.             Field[] f = cl.getDeclaredFields();                       
  7.             int mod;
  8.                        
  9.             System.out.println("Valeur de f.length : " + f.length); /* <----- Il est un peu difficile de connaitre la valeur de f.length à la compilation ... conclusion : cette ligne s'execute et affiche 0 */
  10.            
  11.             for(int i=0; i<f.length ; i++){
  12.                 mod = f[i].getModifiers();
  13.                 res = res + Modifier.toString(mod);
  14.                 res = res + " " + f[i].getType() + " " +
  15.                         f[i].getName() + ";\n";
  16.             }
  17.         return res;
  18.     }


 
 - Et j'ai aussi une classe BebeteStupide qui herite de BebeteAbstraite que je teste dans la methode main ci-dessous :
 

Code :
  1. public static void main(String [] args){   
  2.         java.awt.Color c = new java.awt.Color(15);
  3.         BebeteStupide bet = new BebeteStupide(new ChampDeBebetes(640,480), 20, 20, 2, 30, c);       
  4.         System.out.println("" + bet.toString());
  5.   }


 
Je compile tout ceci sans probleme et voila ce que j'obtiens :  
 

Citation :


run-single:
Valeur de f.length : 0
Noms des attributs :  
tp2bis.bebetes.BebeteStupide
 
..... et la ca se bloque je doit quitter le processus manuellement


 
Voila j'espere avoir été un peu plus clair .


Message édité par Chronoklazm le 09-10-2005 à 16:59:05

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 09-10-2005 à 17:15:05    

Bon la ca bloque plus mais j'ai toujours le tableau de Field qui est de taille 0 :
 

Code :
  1. public static void main(String [] args){
  2.         java.awt.Color c = new java.awt.Color(15);
  3.         BebeteStupide bet = new BebeteStupide(null, 20, 20, 2, 30, c);       
  4.         System.out.println(bet);             
  5.     }


 

Citation :


run-single:
Valeur de f.length : 0
tp2bis.bebetes.BebeteStupide
BUILD SUCCESSFUL (total time: 0 seconds)


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 09-10-2005 à 17:30:39    

Hay, par défaut les variables membres d'un objet en Java elles seraient pas un petit peu private? [:icon12]
 
Je pense que tu devrais lire la description des fonctions Class.getField() et Class.getFields() qu'on peut trouver dans la javadoc [:marc]

Message cité 1 fois
Message édité par masklinn le 09-10-2005 à 17:39:20

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 09-10-2005 à 17:39:51    

masklinn a écrit :

Hay, par défaut les variables members d'un objet en Java ils seraient pas  private? [:icon12]


 
Je pense pas :
 

Code :
  1. class Personne {
  2.   String i; 
  3.   private String nom;
  4.   private int a;
  5.   private int b;
  6.   public Personne(String nom) {
  7.     this.nom = nom;
  8.     this.a = 1;
  9.     this.b = 2;
  10.   }
  11.    public String toString(){
  12.         String res = "";
  13.         Class cl = this.getClass();
  14.         res = res + "" + cl.getCanonicalName() + "\n";
  15.         Field[] f = cl.getDeclaredFields();         
  16.         int mod;       
  17.         System.out.println("" + f.length);
  18.           for(int i=0; i<f.length ; i++){             
  19.               mod = f[i].getModifiers();
  20.               res = res + Modifier.toString(mod);
  21.               res = res + " " + f[i].getType() + " " +
  22.                       f[i].getName() + ";\n";
  23.               //System.out.println("res " + res);
  24.              
  25.              
  26.         }
  27.         return res;
  28.     }
  29. }
  30. public class Test {
  31.    
  32.     /** Creates a new instance of Test */
  33.     public Test() {
  34.        
  35.     }
  36.    
  37.     public static void main(String [] args){
  38.         Personne p= new Personne("Bob" );
  39.         System.out.println(" +++++ \n" + p); 
  40.     }   
  41. }


 
Ca donne :
 

Code :
  1. run-single:
  2. 4
  3. +++++
  4. tp2bis.bebetes.Personne
  5. class java.lang.String i;
  6. private class java.lang.String nom;
  7. private int a;
  8. private int b;
  9. BUILD SUCCESSFUL (total time: 0 seconds)


Message édité par Chronoklazm le 09-10-2005 à 17:40:53

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 09-10-2005 à 17:42:55    

Ouais sauf que là t'appelles getDeclaredFields, initialement t'appelais getFields, s'pas trop le même [:marc]
 
Enfin bon moi je sais pas, tout ce que je peux te dire c'est que j'ai tapé et compilé:

Code :
  1. import java.lang.StringBuilder;
  2. import java.lang.reflect.Field;
  3. public abstract class Bestiole {
  4.     public int x,y;
  5.     public int vitesse;
  6.     public float direction;
  7.    
  8.     public String toString() {
  9.         StringBuilder output = new StringBuilder();
  10.         Class cl = this.getClass();
  11.         Field[] f = cl.getFields();
  12.         output.append("Fields count: " );
  13.         output.append(f.length);
  14.         output.append("\n" );
  15.         for(int i=0; i<f.length; ++i){
  16.             output.append(f[i].getName());
  17.             output.append("\n" );
  18.         }
  19.         return output.toString();
  20.     }
  21. }


Code :
  1. public class Frub extends Bestiole {
  2.     public static void main(String[] args) {
  3.         Frub machin = new Frub();
  4.        
  5.         System.out.println(machin.toString());
  6.     }
  7. }


et qu'à l'exécution de Frub j'ai:

>java Frub
Fields count: 4
x
y
vitesse
direction
 
 
>


 
Et si je ne déclare pas les champs de ma Bestiole en public, je récupère:

>java Frub
Fields count: 0
 
 
>


Message édité par masklinn le 09-10-2005 à 17:47:33

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 09-10-2005 à 17:53:50    

Citation :

Bon la ca bloque plus


Ah ouais ? Ne me dis rien : y'avais du AWT dans l'air ? [:dawa]  
 
Je n'y comprends tjs rien à tes histoires compilation/exécution/build. Un exécution qui se termine par "build successful" -> bordel, c'est quoi cet IDE ? [:pingouino]
 
Ce n'est toujours pas d'une grande clarté, et c'est même plutôt le bordel - tu exposes une mer de bouts de code sans liens entre eux...
 
De toute façon, relis la doc, c'est bien comme Masklinn l'a dit.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 09-10-2005 à 17:54:29    

Citation :

reflecting all the accessible public fields of the class or interface represented by this Class object.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 09-10-2005 à 18:13:02    

Ouais y avais de l'AWT :)
 
Bon ayé j'ai plus ou moins capté ... enfait dans ma classe BebeteAbstraite j'ai pas d'attributs publiques j'ai que des "locaux" (on les appelles comme ca ceux qui sont ni private ni public ?).
 
Ensuite BebeteStupide herite tous les attributs de BebeteAbstraite, et ces attributs herités sont bizzarement pas recuperables avec getFields() ou getDeclaredFields()  ...  (alors que dans mon cours j'ai noir sur blanc : getFields() : NE RENVOI QUE LES ATTRIBUTS PUBLICS, LOCAUX ET HERITES)
 
Bon bref j'ai trouvé une solution hackeuse (huhuh) :
 

Code :
  1. public String toString(){
  2.         //String a renvoyer
  3.         String res = "";
  4.        
  5.         //Recuperation de la classe courante
  6.         Class cl = this.getClass();
  7.        
  8.         //Recuperation de la superclasse
  9.         Class supercl = cl.getSuperclass();
  10.                        
  11.         //Recuperation dess champs de la classe courante
  12.         Field[] f = cl.getDeclaredFields();
  13.        
  14.         //Si il n'y a pas d'attributs dans la classe courante on  
  15.         //regarde dans la cuperclasse
  16.         if(supercl != null && f.length == 0){
  17.             f = supercl.getDeclaredFields();           
  18.         }
  19.        
  20.         System.out.println("Longuer de f " + f.length);
  21.        
  22.         //Nom de la classe courante
  23.         res = res + "" + cl.getCanonicalName();
  24.        
  25.         int mod;
  26.                
  27.         for(int i=0; i<f.length ; i++){
  28.             mod = f[i].getModifiers();
  29.             res = res + Modifier.toString(mod);
  30.             res = res + " " + f[i].getType() + " " +
  31.                     f[i].getName() + ";\n";
  32.         }
  33.         return res;
  34.     }


 
La j'ai bien ce qu'il me faut.
Je passe simplement par la superclasse pour recuperer ces attributs ... apres pas trop envie de generaliser tout ca. (Exemple dans le cas ou la classe courante contient des attributs public qu'on recupere avec getFields() puis avec une boucle on remonte dans la hierarchie d'heritage et on recupere dans chaque superclasse ses attributs locaux, prives etc ...)


Message édité par Chronoklazm le 09-10-2005 à 18:18:58

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 09-10-2005 à 18:18:52    

Et tu fais comment si il y a une superclasse (donc des attributs hérités) et des attributs non hérité? [:marc]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 09-10-2005 à 18:20:50    

masklinn a écrit :

Et tu fais comment si il y a une superclasse (donc des attributs hérités) et des attributs non hérité? [:marc]


 
Enfin c'est cho quand meme ... :sweat:


Message édité par Chronoklazm le 09-10-2005 à 18:45:42

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 09-10-2005 à 19:46:19    

Non en fait c'est tout merdique :
 

Code :
  1. import java.lang.reflect.*;
  2. import java.util.*;
  3. /**
  4. *
  5. * @author Fraer
  6. */
  7. public class Test {
  8.        
  9.     public static void main(String [] args){
  10.         Personne p= new Personne("Vlad" );
  11.         System.out.println(" +++++ \n" + p);       
  12.     }   
  13. }
  14. abstract class Primate{
  15.     private static boolean poilu;
  16. }
  17. abstract class Homme extends Primate{
  18.     private String adn;
  19. }
  20. class Personne extends Homme{
  21.   String i; 
  22.   private String nom;
  23.   private int a;
  24.   private int b;
  25.   public int c;
  26.   public Personne(String nom) {
  27.     this.nom = nom;
  28.     this.a = 1;
  29.     this.b = 2;
  30.     this.c = 3;
  31.   }
  32.     /* Methode toString generique */
  33.     public String toString(){
  34.         //String a renvoyer
  35.         String res = "";
  36.         //La liste finale de Field
  37.         List le = new ArrayList();
  38.                                
  39.         //Recuperation de la classe courante
  40.         Class cl = this.getClass();
  41.        
  42.         //Nom de la classe courante
  43.         res = res + "" + cl.getCanonicalName() + " \n";
  44.        
  45.         //Recuperation des champs de la classe courante
  46.         Field[] f = cl.getDeclaredFields();
  47.        
  48.         //On met les attributs de la classe courante dans la liste
  49.         for(int i=0; i<f.length; i++){
  50.             le.add(i, f[i]);
  51.         }
  52.                        
  53.         //On remonte dans la hierarchie d'heritage  
  54.         while((cl=cl.getSuperclass()) != null)
  55.         {             
  56.             //Si il y a des attributs a prendre
  57.             if(cl.getDeclaredFields().length != 0){
  58.                
  59.                 System.out.println("" + cl.getCanonicalName());
  60.            
  61.                 //On recupere les attributs de la superclasse
  62.                 Field[] tempField = cl.getDeclaredFields();
  63.                
  64.                 //On les met dans la liste generale
  65.                 for(int i = 0; i<tempField.length ; i++){
  66.                     le.add(tempField[i]);
  67.                 }
  68.             }
  69.         }
  70.        
  71.         //Entier pour la methode getModifiers()
  72.         int mod;
  73.                
  74.         //Boucle de formatage
  75.         for(int i = 0; i<le.size(); i++){       
  76.             Field fi = (Field)le.get(i);
  77.             mod = fi.getModifiers();
  78.             res = res + Modifier.toString(mod);
  79.             res = res + " " + fi.getType() + " " +
  80.                     fi.getName() + ";\n";           
  81.         }       
  82.         return res;
  83.     }
  84. }


 

Citation :


tp2bis.bebetes.Personne  
 class java.lang.String i;
private class java.lang.String nom;
private int a;
private int b;
public int c;
private class java.lang.String adn;
private static boolean poilu;
 
BUILD SUCCESSFUL (total time: 0 seconds)


 
En gros la methode getField() je vois pas trop a quoi elle sert ...  :sarcastic:

Message cité 1 fois
Message édité par Chronoklazm le 09-10-2005 à 19:47:55

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 09-10-2005 à 19:57:07    

HOHOHO je peux meme avoir la valeur des attributs  :ouch:  
 

Code :
  1. //Boucle de formatage
  2.         for(int i = 0; i<le.size(); i++){       
  3.             Field fi = (Field)le.get(i);
  4.             mod = fi.getModifiers();
  5.             res = res + Modifier.toString(mod);
  6.             res = res + " " + fi.getType() + " " +
  7.                     fi.getName();
  8.             try{
  9.                 res = res + " " + fi.get(this);
  10.             }catch(Exception e){
  11.             System.out.println(e);
  12.             }
  13.             res = res + "\n";
  14.        
  15.         }


 

Citation :


tp2bis.bebetes.Personne  
 class java.lang.String i null
private class java.lang.String nom Vlad
private int a 1
private int b 2
public int c 3
private class java.lang.String adn
private static boolean poilu


 
Mais c'est formidable  [:chronoklazm]


Message édité par Chronoklazm le 09-10-2005 à 19:57:44

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 09-10-2005 à 22:14:01    

Chronoklazm a écrit :

En gros la methode getField() je vois pas trop a quoi elle sert ...  :sarcastic:


À pas se faire chier avec des récursions sur les superclasses tout simplement [:pingouino]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed