Подтвердить что ты не робот

Как вызвать метод java с использованием имени переменной?

Скажем, у меня есть Method1 (void), Method2 (void)...

Есть ли способ выбрать один из тех, у кого есть переменная?

 String MyVar=2;
 MethodMyVar();
4b9b3361

Ответ 1

Использовать отражение:

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

Ответ 2

Только через отражение. См. Пакет java.lang.reflect.

Вы можете попробовать что-то вроде:

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

Ваш код может отличаться, если у метода есть параметры и отсутствуют все виды обработки исключений.

Но спросите себя, действительно ли это необходимо? Может быть, что-то изменилось в отношении вашего дизайна, чтобы этого избежать. Код отражения трудно понять и медленнее, чем просто вызов obj.someMethod().

Удачи. Счастливое кодирование.

Ответ 3

Вы можете использовать шаблон проектирования Стратегии и сопоставление имеющейся строки с соответствующим конкретным объектом стратегии. Это безопасное и эффективное средство.

Итак, посмотрите HashMap<String,SomeInterfaceYouWantToInvokeSuchAsRunnableWithPseudoClosures>.

Например, что-то вроде:

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

Вы также можете использовать рефлексию или "инвертировать" проблему и использовать полиморфизм

Ответ 4

Я не уверен, как принятый ответ работает для method.invoke() без первого аргумента статического метода, являющегося null (по умолчанию значение фиктивного значения работает). Согласно Учебники Java ™:

Первый аргумент - это экземпляр объекта, в котором этот конкретный метод должен быть вызван. (Если метод статичен, то первый аргумент должен быть нулевым.)

Ниже приводятся полные примеры (Main.java), для статического (по классу) VS нестатического (по экземпляру), плюс дополнительный пример для метод с аргументом, import, класс catch, а также метод суперкласса.

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

Вывод:

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