IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API standards et tierces Java Discussion :

Comment appeler une méthode dont le nom est dans un string?


Sujet :

API standards et tierces Java

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut Comment appeler une méthode dont le nom est dans un string?
    Bonjour, j'ai besoin (comme le dit si bien l'intitulé du post) d'appeler une méthode à partir d'un nom contenu dans un string. Il y a déja une discussion ancienne sur ce sujet mais..je n'arrive pas à faire fonctionner les solutions proposées (je suis débutant ).
    Voila, est-ce que quelqu'un pourrait m'aider?

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Il faut utiliser l'API de reflection...

    a++

  3. #3
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    Grosso modo comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Class classTypes [] = {(new String()).getClass()};
    Method getMethod = entity.getClass().getMethod("nom_methode", classTypes); 
    String args[] = {"param1","param2"};
          			getMethod.invoke(entity, args);

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut
    Merci pour les réponses, mais j'ai le même problème avec les deux:
    J'ai une erreur sur Method m=... : Method can not be resolved to a type.
    J'utilise Eclipse 3.2.2 et jre 1.6.0. Qu'est ce que je peux faire?

  5. #5
    Membre actif Avatar de g0up1l
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    341
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 341
    Points : 294
    Points
    294
    Par défaut
    as tu importé le package 'java.lang.reflect.Method' ?

  6. #6
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Il suffit de rajouter les imports correspondant (Ctrl+Shift+O avec eclipse) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import java.lang.reflect.Method;
    ...
    a++

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut ah..ben non
    Aie j'ai encore du mal...

    J'ai essayé le code de Willoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Class classTypes [] = {(new String()).getClass()};
    Method getMethod = entity.getClass().getMethod("nom_methode", classTypes); 
    String args[] = {"param1","param2"};
          			getMethod.invoke(entity, args);
    mais "entity" can not be resolved.

    J'ai aussi regardé le code de la docu API:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    Object lancerMethode(Object o, Object[] args, String nomMethode) throws Exception
    {
      Class[] paramTypes = null;
      if(args != null)
      {
        paramTypes = new Class[args.length];
        for(int i=0;i<args.length;++i)
        {
          paramTypes[i] = args[i].getClass();
        }
      }
      Method m = o.getClass().getMethod(nomMethode,paramTypes);
      return m.invoke(o,args);
    }
    qui a l'air très bien, sauf que je ne sais pas quoi mettre pour Object o ni de quelles facon écrire les arguments de ma méthode (qui ont l'air d'aller dans "Object[] args").

    Au final, je suis toujours bloqué . Merci pour les réponses!

  8. #8
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    C'est normal si tu le defini nulle part

    Ben si tu veux entity c'est l'objet sur lequel tu veux appeler ta methode.

    Exemple tu as une classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class MonBean{
    private String x;
    public String getX(){return x;}
    public setX(String x){this.x=x;}
    }
    tu defini :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonBean entity=new MonBean();
    entity.setX("chaine");
    ensuite quand tu appelle la methode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Method getMethod = entity.getClass().getMethod("getX", classTypes);

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut Ca avance, petit à petit
    Bien... j'ai tapé le programme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    import java.lang.reflect.Method;
     
    public class MonBean {
    	private String x;
    	public String getX(){return x;}
    	public void setX(String x){this.x=x;}
     
    public static void main (String[] args) {
    		MonBean entity=new MonBean();
    		Class classTypes [] = {(new String()).getClass()};
    		Method getMethod = entity.getClass().getMethod("nom_methode", classTypes); 
    		String args[] = {"param1"};
    		      			getMethod.invoke(entity, args);
    	}
    public void methode(){
    	MonBean entity=new MonBean();
    	Class classTypes [] = {(new String()).getClass()};
    	Method getMethod = entity.getClass().getMethod("nom_methode", classTypes); 
    	String args[] = {"param1"};
    	      			getMethod.invoke(entity, args);
     
    }
     
    }
    et comme d'habitude..dès qu'il y a un message d'erreur..je suis perdu


    Lorsque la commande est dans un main(), j'ai juste un message d'erreur sur "args": duplicate local variable

    par contre, lorsque elle est dans une méthode (la ou je voudrait la mettre dans le vrai programme), plein de rouge apparait :
    unhandled exception NoSuchMethodException

    et pour la ligne getMethod.invoke(entity, args); il y a en deux ou trois. Je suppose que je dois écrire quelque chose du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int choix1;
    choix1=getMethod.invoke(entity, args);
    puisque la méthode que je veux utiliser doit renvoyer un entier, mais eclipse cannot convert object to int.

    Bref, encore beaucoup de questions. Merci de toute aide!

  10. #10
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    1) Ecoute si la methode de MonBean s'appelle getX, il te faut ecrire getX et pas nom_methode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Method getMethod = entity.getClass().getMethod("getX", classTypes);
    2) Si ta methode ne prends pas de parametre, il te faut pas en mettre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getMethod.invoke(entity);
    3) Je mettrais pas tout dans la meme classe, meme fichier. Crees une classe pour Monbean, une autre classe pour appeler la methode

  11. #11
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    Plus exactement, ca ressemblerait a ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Method getMethod = entity.getClass().getMethod("getX", classTypes);
    String [] args = new String[0]; //No arguments
    String valeur = (String)(getMethod.invoke(delobj, args));

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut ca marche toujours pas...
    J'obtiens toujours le même message d'erreur à l'execution du programe... "NoSuchMethodException", alors que la méthode existe bien dans le programme.
    Une idée? Merci d'avance

  13. #13
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par Ireon
    Bonjour, j'ai besoin (comme le dit si bien l'intitulé du post) d'appeler une méthode à partir d'un nom contenu dans un string. Il y a déja une discussion ancienne sur ce sujet mais..je n'arrive pas à faire fonctionner les solutions proposées (je suis débutant ).
    Voila, est-ce que quelqu'un pourrait m'aider?
    Tu le récupères comment le nom de ta méthode dans un String?

  14. #14
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    Bon quel code as-tu produit?
    Car le code que je t'ai donne fonctionne(il est en production actuellement), il faut l'adapter a ta methode!

    Montre voir la classe et la methode que tu veux appeler ainsi que le programme appelant.

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut voila le programme
    Il s'agit d'un programme qui simule le dilemne du prisonnier. Pour le moment, il y a seulement deux strategies, dont les arguments sont muets (mais à terme..avec de la chance... il y en aura d'autres qui utiliseront ces arguments )

    Pour décrire rapidement, il y a deux méthodes qui représentent chacune un comportement: cooperer ou trahir. Des valeurs sont attribuées lors d'un match des deux comportements.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
     
    	import java.io.IOException;
    	import java.lang.reflect.Method;
    	import java.util.TreeMap;
    	import java.util.Vector;
    	import java.io.FileWriter;
    	import java.io.IOException;
    	import java.io.PrintWriter;
     
     
    	public class Strategies {
     
    		public TreeMap<String, Integer> ponderation;
     
    		/* on initialise les valeurs */
    		public void initialise_ponderation()
    		{TreeMap<String,Integer> ponderation= new TreeMap<String,Integer>();
    		ponderation.put("cooperation", 50);
    		ponderation.put("competition", 10);
    		ponderation.put("trahison", 60);
    		ponderation.put("trahi", 0);	
    		}
     
    		/* pour le moment, seulement deux strategies. historique et pos seront utilisés plus tard*/
    		public int gentil(Vector historique , int pos)
    		{	
    			return 1;
    		}		
    		public int mechant(Vector historique , int pos)
    		{	
    			return 0;
    		}
     
     
     
     
    		public void match(String strat1, String strat2,Vector historique) throws Exception
    		{
    			TreeMap resultat= new TreeMap<String,Integer>();
     
     
     
    			/* on initialise le vecteur qui donnera les résultats */
    			resultat.put(strat1, 0);
    			resultat.put(strat2, 0);
     
     
     
    			/* Voila la partie interessante*/
     
     
    			Strategies entity = new Strategies();
     
    			Class classTypes [] = {(new String()).getClass()};
    			Method getMethod = entity.getClass().getMethod(strat1, classTypes); 
     
    			String arg1[] = {"historique","0"};
    			int choix1 = (Integer) (getMethod.invoke(entity, arg1));
     
    			String arg2[] = {"historique","1"};
    			int choix2 = (Integer) (getMethod.invoke(entity, arg2));
     
     
     
     
     
     
     
     
    			/* on attribue les points selon les strategies*/
     
    			if ((choix1==0)&(choix2==0)) 
    			{resultat.put(strat1,ponderation.get("cooperation"));
    			 resultat.put(strat2,ponderation.get("cooperation"));		
    			}
    			if ((choix1==0)&(choix2==1)) 
    			{resultat.put(strat1,ponderation.get("trahi"));
    			 resultat.put(strat2,ponderation.get("trahison"));		
    			}
    			if ((choix1==1)&(choix2==0)) 
    			{resultat.put(strat1,ponderation.get("trahison"));
    			 resultat.put(strat2,ponderation.get("trahi"));		
    			}
    			if ((choix1==1)&(choix2==1)) 
    			{resultat.put(strat1,ponderation.get("competition"));
    			 resultat.put(strat2,ponderation.get("competition"));		
    			}
     
     
    			/* on ecrit le résultat*/
    			PrintWriter ecrire = new PrintWriter(new FileWriter("resultat.txt"));
    			ecrire.print(resultat.entrySet());
    			ecrire.close();
     
     
    		}
     
    		public static void main (String[] args) throws Exception{
    			Strategies entity= new Strategies() ;
    			Vector historique= new Vector();
    			entity.initialise_ponderation();
    			entity.match("mechant", "gentil", historique);
     
    		}
     
     
    }

    J'ai à chaque fois l'erreur "NoSuchMethodException".
    Merci beaucoup de l'aide en tout cas!

  16. #16
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Alors dans ce cas, il ne faut surtout pas utiliser l'introspection...

    Il faut que tu te fasses par exemple une interface qui contient une méthode action(), et tu fais deux classes qui l'implémentent, Cooperer et Trahir.

  17. #17
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    Oui, je suis assez d'accord avec rom, sauf que Cooperer et Trahir represente plutot des actions(ce sont des verbes) que des objets.
    Donc plutot se tourner vers qqch du style Cooperant et Traitre.

    De toute facon ca ne sert pas a grand chose d'invoquer des methodes comme tu l'as fait tu peux tout a fait les appeler en direct.Mais a ta place je m'inspirerais plutot de l'idee de rom.

  18. #18
    Membre actif Avatar de g0up1l
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    341
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 341
    Points : 294
    Points
    294
    Par défaut
    les méthodes gentil et mechant prennent en paramètre un vecteur et un int et non pas une String

  19. #19
    Membre actif Avatar de g0up1l
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    341
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 341
    Points : 294
    Points
    294
    Par défaut
    Je suppose qu'il faut donc revoir ton tableau d'arguments :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Class classTypes [] = {Vector.class, int.class };
    ( je n'ai pas compilé ce code )

  20. #20
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 13
    Points : 7
    Points
    7
    Par défaut code épuré
    En fait, j'ai besoin d'appeler les méthodes par un string car à terme, je voudrais utiliser un tableau xls: dans une colonne le nom des stratégies et dans une autre leur effectif.

    J'ai essayé la suggestion de goupil:en épurant le code au maximum voila ce que ca donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    import java.lang.reflect.Method;
    import java.util.Vector;
     
    public class Comportement {
     
    	// la méthode à appeler
    	public int gentil(Vector historique , int pos) {return 1;}
     
     
    	//l'appel à la méthode
    	public void match(String strat1, Vector historique) throws Exception
    	{
    		Comportement entity = new Comportement();
     
    		Class classTypes [] = {Vector.class, int.class };
    		Method getMethod = entity.getClass().getMethod(strat1, classTypes); 
     
    		String arg1[] = {"historique","0"};
    		int choix1 = (Integer) (getMethod.invoke(entity, arg1));
    	}
     
     
     
     
    	public static void main (String[] args) throws Exception{
    		Vector historique= new Vector();	
    		Comportement entity = new Comportement();
     
    		entity.match("gentil", historique);
     
    	}

    J'ai aussi essayé avec les versions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Class classTypes [] = {(new String()).getClass() };
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Class classTypes [] = {(new String()).getClass(),(new String()).getClass() };
    (je me suis dit: on sais jamais...après tout, j'ai deux arguments, non?)
    Bref, ca ne marche pas non plus.

    J'ai droit à plusieurs erreurs lorsque je l'execute...je ne sais pas ce qui cloche, ca ressemble beaucoup au code théorique pourtant, non?

    Merci aussi pour ta suggestion Rom, le souci c'est que je suis grand débutant en java et en langage orienté objet (j'ai plutot connu CamL..) et donc je ne vois pas ce que ca veux dire! .

    Est ce que quelqu'un arrive à faire marcher le petit bout de code? Merci à tous en tout cas

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 3
    Dernier message: 25/06/2012, 12h55
  2. appeler une fonction dont le nom est dans un parametre
    Par djams9 dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 15/06/2011, 11h42
  3. Réponses: 3
    Dernier message: 05/02/2007, 09h41
  4. Réponses: 3
    Dernier message: 05/10/2006, 18h52
  5. Appel de methode dont le nom est dans une variable
    Par osopardo dans le forum Langage
    Réponses: 1
    Dernier message: 24/11/2005, 20h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo