[JAVA] cast, comment je fais ??

cast, comment je fais ?? [JAVA] - Programmation

Marsh Posté le 02-04-2002 à 15:12:18    

Alors, voilà, j'ai un objet Class, et un autre de type string.
Je veux convertir la string dans le type de l'objet Class... J'ai beau regarder je vois pas comment faire, à part avec des instanceof et plein de test,mais c'est crade ça...
 
Y'a pas moyen de faire un truc du genre
Class c
String s
Object o
 
o= (c)s;  
 
pour qu'il me le fasse tout seul ?
 
Help, siouplé...

Reply

Marsh Posté le 02-04-2002 à 15:12:18   

Reply

Marsh Posté le 02-04-2002 à 15:13:32    

Fucky_Fuck a écrit a écrit :

Alors, voilà, j'ai un objet Class, et un autre de type string.
Je veux convertir la string dans le type de l'objet Class... J'ai beau regarder je vois pas comment faire, à part avec des instanceof et plein de test,mais c'est crade ça...
 
Y'a pas moyen de faire un truc du genre
Class c
String s
Object o
 
o= (c)s;  
 
pour qu'il me le fasse tout seul ?
 
Help, siouplé...  




 
o= (Class)s;
Mais c pas possoble en fait ça. à la limite un  
o= (Object)s;

 

[jfdsdjhfuetppo]--Message édité par El_Gringo--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 02-04-2002 à 15:13:53    

est ce valide au moins?
 
C'est quoi ton type Class?


---------------
Just because you feel good does not make you right
Reply

Marsh Posté le 02-04-2002 à 15:21:42    

En fait, je veux invoquer une méthode du type setX( unobjet)
et tout les arguments des méthodes sont stockés dans des tableaux de String. Pour que ça marche, il faut donc que je convertisse la String en int,boolean... afin que la méthode puisse être invoquée.
 
je recupère le type à avoir dans un objet Class
je sais qu'il va toujours pouvoir transtyper de la string vers le type voulu.
 
je fais alors :
 
Class p = propertyList[wNb].getPropertyType(); //récupère le type
o[0]= (p) tab[wNb].getText();  //o[0] est un Object, getText me renvoie une String
 
 
try {propertyList[wNb].getWriteMethod().invoke(currentObject,o);}
// récupère la méthode et tente de l'invoquer sur l'objet avec  
//l'argument voulu
// CurrentObject est un objet déclaré plus haut...
...
 
seulement, il me dit qu'il ne peut transtyper parce qu'il ne connait la class p... Alors faut peut être faire autrement, mais je vois pas...

 

[jfdsdjhfuetppo]--Message édité par Fucky_Fuck--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 02-04-2002 à 15:32:46    

:heink:  :heink:  :heink:


---------------
Just because you feel good does not make you right
Reply

Marsh Posté le 02-04-2002 à 16:33:54    

DarkLord a écrit a écrit :

est ce valide au moins?
 
C'est quoi ton type Class?  




 
8|...Dark!! Rhôôôo!!!
 
java.lang.Class, tu me déçois, là! :D Mais bon, si t'as picolé autant que moi ce ouikende, je te pardonne! :D

Reply

Marsh Posté le 02-04-2002 à 16:50:02    

si j'ai bien compris, c'est de l'invocation dynamique que tu veiux faire.
tu fais un Class.forName("taClasse" ), puis newInstance sur ce Class, tu cast le résultat dans le type attendu, et tu appelle la méthode que tu veux ...

Reply

Marsh Posté le 02-04-2002 à 17:13:13    

gfive a écrit a écrit :

 
 
8|...Dark!! Rhôôôo!!!
 
java.lang.Class, tu me déçois, là! :D Mais bon, si t'as picolé autant que moi ce ouikende, je te pardonne! :D  




 
non je pensais que quand il disait type classe c'etait une classe à lui. MAis comme il donnait pas la définition ...
 
C'est pas clair son truc de toutes façons!  :fou:


---------------
Just because you feel good does not make you right
Reply

Marsh Posté le 02-04-2002 à 17:19:53    

Fucky_Fuck a écrit a écrit :

 
Class p = propertyList[wNb].getPropertyType(); //récupère le type
o[0]= (p) tab[wNb].getText();  //o[0] est un Object, getText me renvoie une String
try {propertyList[wNb].getWriteMethod().invoke(currentObject,o);}
// récupère la méthode et tente de l'invoquer sur l'objet avec  
//l'argument voulu
// CurrentObject est un objet déclaré plus haut...
...
 
seulement, il me dit qu'il ne peut transtyper parce qu'il ne connait la class p... Alors faut peut être faire autrement, mais je vois pas...  




c'est quoi tout tes objets la ??? c'est des trucs fait maison, nan ... l'exception elle est généré par qui ? par un de ces objets ?

Reply

Marsh Posté le 02-04-2002 à 18:12:37    

Bon, je la refais de manière plus claire, mais bon, c'est compliqué, même moi je m'y perd...
 
j'ai déclaré  :  
PropertyDescriptor [] propertyList // propertydescriptor -> JDK
Object currentObject
JTextField tab []
 
(je sais j'ai pas recopier la déclaration complète, mais ils sont tous instanciés, pas de pb)
 
et je fais ça :
 
class ActionTab implements ActionListener
{
 private int wNb;
 
 ActionTab(int i) {wNb=i;}
   
 public void actionPerformed (ActionEvent evt)  
 {
 
 Class p = propertyList[wNb].getPropertyType();
 Object [] o=new Object [1];
 o=(p) tab[wNb].getText();
 
 try {propertyList[wNb].getWriteMethod().invoke (currentObject,o);}
 catch(IllegalAccessException e) {return;}
 catch(IllegalArgumentException ee) {return;}
 catch(InvocationTargetException eee) {return;}
 catch (NullPointerException eeee) {return;}
 catch (ExceptionInInitializerError eeeee)  {return;}
}
}
 
c'est la méthode invoke qui génère les exception...
 
Bon pour l'instant je me suis débrouillé autrement, mais j'aimerai bien savoir si il y a moyen de faire comme ça...
 
Un autre point, invoke veut absolument un object [], alors je suis obligé de déclarer un object[1], et je trouve ça ridicule, pas moyen de faire autrement ???
 
Désolé, si ça vous parait con, ou pas du tout dans la philosophie java, mais je fais du C++ normalement, et le je dois dire que le java ça me :gun:

Reply

Marsh Posté le 02-04-2002 à 18:12:37   

Reply

Marsh Posté le 02-04-2002 à 18:27:09    

donne le trace de l'exception parce que la je vois pas ...
pour l'obtenri il faute que tu remplace par ce bout de code :  
 
try {
   propertyList[wNb].getWriteMethod().invoke (currentObject,o);
} catch(Exception e) {
   e.printStackTrace(System.err);
}

Reply

Marsh Posté le 02-04-2002 à 18:39:28    

Fucky_Fuck a écrit a écrit :

 
Un autre point, invoke veut absolument un object [], alors je suis obligé de déclarer un object[1], et je trouve ça ridicule, pas moyen de faire autrement ???




 
non, parce que si tu cherches à invoquer une méthode qui a plusieurs arguments, tu ferais comment, hein??? Pis bon, trouver ridicule, c'est bien joli, mais si c'est fait comme ça, c'eszt clairement pas par hasard, les codeurs de chez Sun ne sont pas des tanches, donc, il vaut clairement mieux chercher à comprendre pourquoi ils ont fait d'une façon qu'on comprend pas, plut^ot que de dire que c'est de la merde...
 
 
[citation]
Désolé, si ça vous parait con, ou pas du tout dans la philosophie java, mais je fais du C++ normalement, et le je dois dire que le java ça me :gun:  
[/citation]
 
bah, c pas forcément con, ni hors de la philmosophie Java, c'est de la reflexivité, ça s'utilise, mais bon, on sait pas si c'est utilisé à bon escient, puisqu'on connait pas le reste du truc...Bon, alors sinon, elle génère quelles exceptions, ta mérthode??? Pasque si on sait lesquelles elle génère, ça nous aidera! ;)
Bon, sinon, j'imagine que la méthode 'getText' de ta classe p, retourne une String, non??? (sinon, son nom est mal choisi, mais bon) Et tu met une String en paramètre d'une méthode qui attend un tableau d'objets (invoke), donc, déjà, c'est foireux dans le principe...  
 
Déjà, avec :  
 
Object[] o = { (p) tab[wNb].getText(); };  
 
ca marchera peut être mieux, pasque ton "o=(p) tab[wNb].getText();", j'ai un doute, c'est déjà étonnant que ça compile...
 
Bon, tu nous donnes plus de détails, et promis, on va te trouver ça! :D

Reply

Marsh Posté le 02-04-2002 à 21:54:11    

gfive a écrit a écrit :

 
Bon, tu nous donnes plus de détails, et promis, on va te trouver ça! :D  




ouais !!! on va pas se laisser démonter par une bete introspection non plus !!! :D

Reply

Marsh Posté le 02-04-2002 à 22:07:06    

benou -> non,je ne peux pas te donner la trace de l'exception, c'est à la compilation qu'il me dit qu'il ne trouve pas la classe p
 
gfive  
 
-> Je ne disais pas que de passer Object [] était ridicule, je pensais qu'il y avait juste moyen de lui faire croire qu'un object seul pouvait être un object[] (en c, il m'aurait demandé un pointeur, et j'aurais mis & devant le nom de mon objet...). Je pensais juste qu'il y avait plus beau que object [1]... d'ailleurs, il y a, tu me l'as mis en dessous...
 
-> Oui, la reflexivité est utilisée à bon escient, je fais un genre de delphi simplifié pour mes camarades qui ont du mal en JAVA, alors faut que je puisse appeler les setX et getX pour n'importe quel composant...
 
-> [citation]
Bon, sinon, j'imagine que la méthode 'getText' de ta classe p, retourne une String, non??? (sinon, son nom est mal choisi, mais bon) Et tu met une String en paramètre d'une méthode qui attend un tableau d'objets (invoke), donc, déjà, c'est foireux dans le principe...  
[/citation]
 
euh là je crois que t'as mal lu... getText() est appliquée à un JTextField, et il y a devant un (p) qui était censé me convertir la string en int,boolean (le type qui est dans p)...
 
 
ce que tu m'as donné, j'ai essayé et il me met (à la compilation) cannot resolve symbol : class p
 
Bon j'ai fait autrement pour l'instant :
 
String s= tab[wNb].getText();
Class p = propertyList[wNb].getPropertyType();
Object [] o=new Object[1];
 
if (p.getName()=="java.lang.String" ) {o[0]=new String(s);return;}
if (p.getName()=="boolean" ) {o[0]= new Boolean(s);return;}
if (p.getName()=="int" ) {o[0]= new Integer(s);return;}
if (p.getName()=="float" ) {o[0]= new Float(s);return;}
if (p.getName()=="double" ) {o[0]= new Double(s);return;}
 
try {propertyList[wNb].getWriteMethod().invoke(currentObject,o);}
catch(IllegalAccessException e) {return;}
catch(IllegalArgumentException ee) {return;}
catch(InvocationTargetException eee) {return;}
catch (NullPointerException eeee) {return;}
catch (ExceptionInInitializerError eeeee)  {return;}
 
ça ça marche, mais bon j'ai des if partout, et c'est pas beau...

 

[jfdsdjhfuetppo]--Message édité par Fucky_Fuck--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 02-04-2002 à 22:33:09    

ATTENTION :
tu fais des == avec des chaines de caractère... ca marche pas.
Dans ton cas ca marche, mais c'est du à l'implementation de la JVM. Il faut faire passer par la méthode equals de la classe String.
 
Ensuite, plutot que de comparer par le nom, tu peux faire comme ca :
 
if (p == String.class) {o[0]=new String(s);return;}  
 
ensuite, tes tests avec les boolean et les int ne seront jamais vrai : boolean, char, int, double, etc ... sont des types primitifs, pas des classes => tes test n'ont pas vriment de sens ...  
Dans les cas où tu as besoin d'utiliser des objets, tu peux utiliser les classes Boolean, Character, Integer, etc ...
 
Ensuite, tu me dis que l'erreur est à la compile, tu pourrais donner le message exacte ? T'es sur que c'est pas un bete problème de CLASSPATH ?

Reply

Marsh Posté le 02-04-2002 à 22:46:28    

Merci pour le .equals, ça je savais pas
 
les tests avec les boolean,int,double... ça marche, j'ai vérifié (en fait,getPropertyType, ça renvoie le type de retour d'une fonction, alors s'ils ne pouvait pas renvoyer des int,double... il seraient emmerdé...), c'est vari que c'est parfois bien chiant que les int,double... ne soient pas des classes, mais là ça marche...
 
 
Message d'erreur :
 
.\inspector.java:365 : cannot resolve symbol
symbol : class p
location class inspector.ActionTab
  Object[] o = { (p) tab[wNb].getText()};
     
 
Voici une partie du code...
 
 
class inspector  extends JFrame
{  
 
///// là y'a du code qui sert à rien ici ///////
 
 
class ActionTab implements ActionListener
 {
  private int wNb;
     
  ActionTab(int i) {wNb=i;}
     
  public void actionPerformed (ActionEvent evt)  
  {
   
  Class p = propertyList[wNb].getPropertyType();
  Object [] o={(p) tab[wNb].getText()};
 
  try {propertyList[wNb].getWriteMethod().invoke (currentObject,o);}
  catch(IllegalAccessException e) {return;}
  catch(IllegalArgumentException ee) {return;}
  catch(InvocationTargetException eee) {return;}
  catch (NullPointerException eeee) {return;}
  catch (ExceptionInInitializerError eeeee){return;}
  }
 
 }
   
}
 
 
à savoir que si j'essaie Object [] o={(inspector.ActionTab.p) tab[wNb].getText()};
ça ne marche pas non plus...

 

[jfdsdjhfuetppo]--Message édité par Fucky_Fuck--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 02-04-2002 à 23:25:28    

Fucky_Fuck a écrit a écrit :

les tests avec les boolean,int,double... ça marche, j'ai vérifié (en fait,getPropertyType, ça renvoie le type de retour d'une fonction, alors s'ils ne pouvait pas renvoyer des int,double... il seraient emmerdé...), c'est vari que c'est parfois bien chiant que les int,double... ne soient pas des classes, mais là ça marche...



 
ha .... ca m'étonne vraiment beaucoup ! les types primitfs auraient un objet Class associé ? je trouve ca louche ! va falloir que je creuse ! ;)

Reply

Marsh Posté le 02-04-2002 à 23:28:02    

y a un truc bizare : tu as une classe qui s'appelle p ????
Parce que t'as aussi une variable qui s'appelle p ...
c'est louche nan ?

Reply

Marsh Posté le 02-04-2002 à 23:48:06    

ben non, j'ai pas de classe p, p, c'est un objet de type Class qui reçoit la classe vers laquelle je veux caster...
 
   Pour les types primitifs, peut être qu'il m'a fait une conversion implicite vers un Integer, Double... non ? parce que dans le JDK, il est écrit que invoke se débrouille pour se dépètrer du mélange du genre Integer/int
 
mais en tout cas, quand j'affiche le class.getName(), il m'affiche bien int...

Reply

Marsh Posté le 02-04-2002 à 23:54:21    

Houlà, oui, ayet, j'ai compris ce que tu veux faire, et c'est normal que ça marche pas! :D
 
Bon, en effet, tu fais un Cast vers une classe qui n'est pas connue à la compil (puisque tu met récupère cet objet Class à partir de getPropertyType(), et ça, je doute fort que Java puisse le faire (je doute q'un seul language fortement typé puisse le faire, d'ailleurs, mais bon, j'ai pas la science infuse non plus, alors je peux me tromper)
Alors bon...'tain, quel bordel, ton truc! :D:D
Tu veux récupérer une valeur en texte dans un champ, et caster ce truc à partir d'un nom de classe, et récupérer un Objet que tu passera à la méthode Invoke (on passe toujours des Objets à Invoke, et c'est un méecanisme interne de la JVM qui se charge de transformer les Integer en int, les Float en float, etc...)
 
Donc, tu es passablement embêté, parce que en Java, caster un String en Integer ou en quoi que ce soit d'autre qui n'est pas une sous-classe de String (ce qui n'existe pas, puisque String est finale) ou une super-classe de String, c'est absolument impossible, même si cette chaîne contient le caractère '1'!!
 
Donc, en gros tu est très très embeté!! :cdy:
Je sais pas trp comment tu pourrais t'en tirer...je vais voir ça avec un pote qui maitrise la reflectivité comme un gros porc, et je t'en reparle demain.

Reply

Marsh Posté le 03-04-2002 à 00:07:21    

ouais ok, c'est un cast dynamique que tu voulais faire, mais je ne pense pas que tu puisse le faire. D'ailleur je n'en vois pas l'intérêt.
 
Toi ce que tu veut c'est pouvoir parser une chaine de caractère en un certain type que tu ne connaît pas à l'avance  ... mais ca c'est pas possible : imagine que tu créés une nouvelle classe : comment veux tu que la JVM sache comment traduire une chaine de caracère en cette classe ?
 
Le seul moyen que je connais qui va marcher pour tous les types de base en java c'est de passer par le construteur : les objets de bases de Java (Integer, Float, etc...) ont tous un constructeur à partir d'une chaine de caractère.

Reply

Marsh Posté le 03-04-2002 à 00:23:27    

merci gfive...
 

benou a écrit a écrit :

ouais ok, c'est un cast dynamique que tu voulais faire, mais je ne pense pas que tu puisse le faire. D'ailleur je n'en vois pas l'intérêt.
 
Toi ce que tu veut c'est pouvoir parser une chaine de caractère en un certain type que tu ne connaît pas à l'avance  ... mais ca c'est pas possible : imagine que tu créés une nouvelle classe : comment veux tu que la JVM sache comment traduire une chaine de caracère en cette classe ?
 
Le seul moyen que je connais qui va marcher pour tous les types de base en java c'est de passer par le construteur : les objets de bases de Java (Integer, Float, etc...) ont tous un constructeur à partir d'une chaine de caractère.  




 
->c'est vrai qu'en fait c'était pas très bien réfléchi tout ça, ça me paraissait tellement évident pour des types simples que j'ai pas penser au reste...
 
->ouais, mais pour faire ça, il faut d'abord que je teste de quel type il est -> on en revient aux if ( String.equals...) de tout à l'heure...
 
ou alors, il faut que je fasse un truc du genre
Class p=ropertyList[wNb].getPropertyType();
Object o = p.newInstance();  
 
mais là, je suis bloqué parce que je peux pas passer ma String au newInstance...

 

[jfdsdjhfuetppo]--Message édité par Fucky_Fuck--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 03-04-2002 à 02:46:59    

ben nan, tu fais ca :
 
String laValeurDeLObjet = ...; // la valeur de ton objet en chaine de caractere que tu recupere je sais pas ou ...
Class taClass = propertyList[wNb].getPropertyType();  
java.lang.reflect.Constructor constr = taClass.getConstructor(new Class[] {String.class});
Object obj = constr.newInstance( new String[] {laValeurDeLObjet});

 
et voila !

 

[jfdsdjhfuetppo]--Message édité par benou--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 03-04-2002 à 09:07:57    

Benou : Ouais, ça peut marcher, ça, c pas mal, mais si tu n'as pas de constructeur avec une String en paramètre, t'es eu....Donc, bon, pour les types de base, ça va marcher, mais dès qu'il voudra aller à du plus compliqué, il sera embêté, scrogneugneu!

Reply

Marsh Posté le 03-04-2002 à 09:20:27    

gfive a écrit a écrit :

Benou : Ouais, ça peut marcher, ça, c pas mal, mais si tu n'as pas de constructeur avec une String en paramètre, t'es eu....Donc, bon, pour les types de base, ça va marcher, mais dès qu'il voudra aller à du plus compliqué, il sera embêté, scrogneugneu!  




ouais c'est clair ... mais je vois pas comment faire mieux ...

Reply

Marsh Posté le 03-04-2002 à 09:40:21    

bah, tu peux faire un 'parser' : une méthode qui prend un objet Class et une String en paramètre, et qui te retourne un Objet qui est une instance de la classe construite à partir de la chaîne.....comme ça, le jour où tu veux ajouter de nouveaux types, tu n'a que cette méthode à modifier....non??
 
 
genre, avec ton appel reflectif au constructeur, et les gestion de cas particulier dans le catch de la NoSuchMethodexception qui est lancée si le contructeur n'existe pas...

Reply

Marsh Posté le 03-04-2002 à 10:14:03    

gfive a écrit a écrit :

bah, tu peux faire un 'parser' : une méthode qui prend un objet Class et une String en paramètre, et qui te retourne un Objet qui est une instance de la classe construite à partir de la chaîne.....comme ça, le jour où tu veux ajouter de nouveaux types, tu n'a que cette méthode à modifier....non??
 
 
genre, avec ton appel reflectif au constructeur, et les gestion de cas particulier dans le catch de la NoSuchMethodexception qui est lancée si le contructeur n'existe pas...  




ben moi je dirais plutot que si on veut ajouter un type, on lui mets un constructeur avec une chaine de caratère et ca roule ! :)

Reply

Marsh Posté le 03-04-2002 à 11:29:35    

bah ouais, mais ça marche que pour les classes que tu as écrit toi, et pas pour celles de l'API, c'est là que le bat blesse!

Reply

Marsh Posté le 03-04-2002 à 11:38:29    

Merci Benou, c'est super ton truc, j'adopte !!!
Mais gfive a raison, pour un truc du genre Color, ça marche pas... Je fais donc un mixe des deux méthodes -> constructeur pour les types primitifs et parser pour les autres...
 
Merci beaucoup de vous être donné tant de mal pour comprendre et résoudre le problème... :jap::jap::jap:

Reply

Marsh Posté le 03-04-2002 à 11:44:23    

De rien, de rien.....C'est 15? et un mars.. masi je prends pas les chèques! :D

Reply

Marsh Posté le 03-04-2002 à 14:33:02    

gfive a écrit a écrit :

bah ouais, mais ça marche que pour les classes que tu as écrit toi, et pas pour celles de l'API, c'est là que le bat blesse!  




ouais ... il faudrait prendre ton idée (pour les cas où il n'y pas de constructeur à partir d'une chaine) : gérer une map de parser un peu à la façon des drivers JDBC : tu fais un Class.forName("parser.StringToColor" ), et ca l'enregistre automatiquement auprès de ta map. Comme ca, l'ajout de nouveau parser se fait sans changer une ligne de code. Ca peut être sympa à faire comme truc !

Reply

Marsh Posté le 03-04-2002 à 14:34:48    

Fucky_Fuck a écrit a écrit :

Merci Benou, c'est super ton truc, j'adopte !!!
Mais gfive a raison, pour un truc du genre Color, ça marche pas... Je fais donc un mixe des deux méthodes -> constructeur pour les types primitifs et parser pour les autres...
 
Merci beaucoup de vous être donné tant de mal pour comprendre et résoudre le problème... :jap::jap::jap:  




de rien ! C'était intéressant comme problème :jap:
 
plutot que de gérér le cas des types primitif à part, moi je testerais plutot l'existence d'un constructeur ayant paramètre une chaine de caractère ...

Reply

Marsh Posté le 04-04-2002 à 15:43:58    

j'ai lu un truc qui m'a refait pensé à ce post.
 
plutot que d'utiliser le constructeur pour créer ton objet à partir d'une chaine, tu devrait plutot utiliser la méthode static valueOf(String). Elle existe pour tous les Wrapper (Integer, Float, etc ...) et c'est plus propre !
Ca a l'air d'être une sorte de convention ...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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