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

时间:2022-11-02 23:41:45

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

4 个解决方案

#1


33  

Use reflection:

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

#2


9  

Only through reflection. See the java.lang.reflect package.

只有通过反思。请参阅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.

祝好运。快乐的编码。

#3


6  

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 查找。 ,someinterfaceyouwanttoinvokesuchasrunnablewithpseudoclosures>

E.g., something along the lines of:

例如,类似于:

final static YourType reciever = this;HashMap<String,Runnable> m = new HashMap<String,Runnable> {{    add("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

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

#4


0  

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:

我不确定如果没有静态方法的第一个参数为null(尽管虚拟值仍然有效),method.invoke()接受的答案是如何工作的。根据The Java™Tutorials:

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

第一个参数是要在其上调用此特定方法的对象实例。 (如果方法是静态的,则第一个参数应为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, import necessary class, catch exception, and also superclass method example.

下面显示了一个完整的示例(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: 10000by instancecalls super protected method by instancecalls super public method by instance$ 

#1


33  

Use reflection:

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

#2


9  

Only through reflection. See the java.lang.reflect package.

只有通过反思。请参阅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.

祝好运。快乐的编码。

#3


6  

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 查找。 ,someinterfaceyouwanttoinvokesuchasrunnablewithpseudoclosures>

E.g., something along the lines of:

例如,类似于:

final static YourType reciever = this;HashMap<String,Runnable> m = new HashMap<String,Runnable> {{    add("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

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

#4


0  

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:

我不确定如果没有静态方法的第一个参数为null(尽管虚拟值仍然有效),method.invoke()接受的答案是如何工作的。根据The Java™Tutorials:

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

第一个参数是要在其上调用此特定方法的对象实例。 (如果方法是静态的,则第一个参数应为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, import necessary class, catch exception, and also superclass method example.

下面显示了一个完整的示例(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: 10000by instancecalls super protected method by instancecalls super public method by instance$