|
Dernière réponse | |
---|---|
Sujet : [JAVA] cast, comment je fais ?? | |
benou | 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 ... |
Aperçu |
---|
Vue Rapide de la discussion |
---|
benou | 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 ... |
benou |
|
benou |
|
gfive | De rien, de rien.....C'est 15? et un mars.. masi je prends pas les chèques! :D |
fucky_fuck | 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: |
gfive | 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! |
benou |
|
gfive | 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... |
benou |
|
gfive | 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! |
benou | 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] |
fucky_fuck | merci gfive...
[jfdsdjhfuetppo]--Message édité par Fucky_Fuck--[/jfdsdjhfuetppo] |
benou | 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. |
gfive | 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. |
fucky_fuck | 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... |
benou | 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 ? |
benou |
|
fucky_fuck | 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] |
benou | 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 ? |
fucky_fuck | 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] |
benou |
|
gfive |
|
benou | 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); } |
fucky_fuck | 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: |
benou |
|
darklord |
|
benou | 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 ... |
gfive |
|
darklord | :heink: :heink: :heink: |
fucky_fuck | 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] |
darklord | est ce valide au moins?
C'est quoi ton type Class? |
El_gringo |
[jfdsdjhfuetppo]--Message édité par El_Gringo--[/jfdsdjhfuetppo] |
fucky_fuck | 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é... |