web-dev-qa-db-fra.com

comment appeler une méthode Java en utilisant un nom de variable?

Dites que j'ai Method1 (void), Method2 (void) ...

Y a-t-il un moyen de choisir l'un de ceux avec une variable? 

 String MyVar=2;
 MethodMyVar();
19
Adam Outler

Utilisez la réflexion:

Method method = WhateverYourClassIs.class.getDeclaredMethod("Method" + MyVar);
method.invoke();

Seulement par la réflexion. Voir le package Java.lang.reflect.

Vous pouvez essayer quelque chose comme:

Method m = obj.getClass().getMethod("methodName" + MyVar);
m.invoke(obj);

Votre code peut être différent si la méthode a des paramètres et qu'il manque toutes sortes de gestion des exceptions.

Mais demandez-vous si cela est vraiment nécessaire? Quelque chose peut être changé dans votre conception pour éviter cela. Le code de réflexion est difficile à comprendre et est plus lent que le simple appel de obj.someMethod().

Bonne chance. Bonne codage.

9
Todd

Vous pouvez utiliser le modèle de conception Stratégie et un mappage de la chaîne que vous avez sur l'objet de stratégie concret correspondant. C'est le moyen sûr et efficace.

Alors, ayez un HashMap<String,SomeInterfaceYouWantToInvokeSuchAsRunnableWithPseudoClosures> look-up.

Par exemple, quelque chose comme:

final static YourType reciever = this;
HashMap<String,Runnable> m = new HashMap<String,Runnable> {{
    put("a", new Runnable() {
       @Override public void run () {
         reciever.a();
       }
    });
    ....
}};
// but check for range validity, etc.
m.get("a").run()

Vous pouvez également utiliser la réflexion ou "inverser" le problème et utiliser le polymorphisme

6
user166390

Je ne sais pas comment fonctionne la réponse acceptée pour method.invoke() sans que le premier argument de la méthode statique soit null (la valeur factice factice fonctionne toujours). Selon Les tutoriels Java ™ :

Le premier argument est l'instance d'objet sur laquelle ce .__ particulier. méthode doit être appelée. (Si la méthode est statique, le premier argument Devrait être null.)

Ce qui suit montre des exemples complets (Main.Java), pour static (par classe) VS non statique (par instance), ainsi qu'un exemple supplémentaire pour la méthode avec l'argument, import classe nécessaire, exception catch et également exemple de la méthode superclass

import Java.lang.reflect.Method;
import Java.lang.reflect.InvocationTargetException;

class Love {
   protected void Method4() {
        System.out.println("calls super protected method by instance");
    }

   public void Method5() {
        System.out.println("calls super public method by instance");
    }
}

class Main extends Love {

    static void Method2(int y) {
        System.out.println("by class: " + y);
    }

    void Method3(String y) {
        System.out.println(y);
    }

    public static void main(String[] args) {

        String MyVar = "2";
        String MyAnotherVar = "3";
        String MySuperVar = "4";
        String MySuperPublicMethodVar = "5";
        Main m = new Main();

       try {
            Method method = Main.class.getDeclaredMethod("Method" + MyVar, int.class); //by class
            Method anotherMethod = m.getClass().getDeclaredMethod("Method" + MyAnotherVar, String.class); //by instance
            Method superMethod = m.getClass().getSuperclass().getDeclaredMethod("Method" + MySuperVar); //super method by instance, can be protected
            Method superPublicMethod = m.getClass().getMethod("Method" + MySuperPublicMethodVar); //getMethod() require method defined with public, so even though sublcass calls super protected method will not works
            try {
                method.invoke(null, 10000);//by class
                anotherMethod.invoke(m, "by instance"); //by instance
                superMethod.invoke(m); //super method by instance
                superPublicMethod.invoke(m); //super's public method by instance
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }

       } catch (NoSuchMethodException e) {
           throw new RuntimeException(e);
       } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
       }
    }
}

Sortie:

$ javac Main.Java
$ Java Main 
by class: 10000
by instance
calls super protected method by instance
calls super public method by instance
$ 
0
林果皞