如何使用变量名调用java方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4138527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 12:00:19  来源:igfitidea点击:

how to call a java method using a variable name?

javavariablesmethods

提问by Adam Outler

Say I have Method1(void), Method2(void)...

假设我有 Method1(void), Method2(void)...

Is there a way i can chose one of those with a variable?

有没有办法我可以选择其中一个变量?

 String MyVar=2;
 MethodMyVar();

采纳答案by Nathan Hughes

Use reflection:

使用反射:

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

回答by Nathan Hughes

You could use the Strategy design pattern and a mapping from the string you have to the corresponding concrete strategy object. This is the safe and efficient means.

您可以使用策略设计模式和从您拥有的字符串到相应的具体策略对象的映射。这是安全有效的手段。

So, have a HashMap<String,SomeInterfaceYouWantToInvokeSuchAsRunnableWithPseudoClosures>look-up.

所以,HashMap<String,SomeInterfaceYouWantToInvokeSuchAsRunnableWithPseudoClosures>来看看吧。

E.g., something along the lines of:

例如,类似于以下内容:

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()

You could also use reflection or "invert" the problem and use polymorphism

您还可以使用反射或“反转”问题并使用多态

回答by Todd

Only through reflection. See the java.lang.reflectpackage.

只能通过反思。请参阅java.lang.reflect包装。

You could try something like:

你可以尝试这样的事情:

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

Your code may be different if the method has parameters and there's all sorts of exception handling missing.

如果方法有参数并且缺少各种异常处理,您的代码可能会有所不同。

But ask your self if this is really necessary? Can something be changed about your design to avoid this. Reflection code is difficult to understand and is slower than just calling obj.someMethod().

但是问问你自己这是否真的有必要?是否可以更改您的设计以避免这种情况。反射代码难以理解,而且比仅仅调用obj.someMethod().

Good luck. Happy Coding.

祝你好运。快乐编码。

回答by Fruit

I'm not sure how the accepted answer works for method.invoke()without first argument of static method being null(put dummy value still works though). According to The Java? Tutorials:

我不确定在method.invoke()没有静态方法的第一个参数的情况下接受的答案如何工作null(尽管放置虚拟值仍然有效)。根据Java? 教程

The first argument is the object instance on which this particular method is to be invoked. (If the method is static, the first argument should be null.)

第一个参数是要在其上调用此特定方法的对象实例。(如果该方法是静态的,则第一个参数应为空。)

The following shows a complete examples (Main.java), for both static(by class) VS non-static(by instance), plus additional example for method with argument, importnecessary class, catchexception, and also superclass methodexample.

下面显示了一个完整的示例(Main.java),静态(按类)VS 非静态(按实例),以及带有参数的方法的附加示例,导入必要的类,捕获异常,以及超类方法示例。

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);
       }
    }
}

Output:

输出:

$ javac Main.java
$ java Main 
by class: 10000
by instance
calls super protected method by instance
calls super public method by instance
$