Вызов функции по имени, полученному из строки java - PullRequest
3 голосов
/ 31 мая 2010

Я хотел бы иметь возможность вызывать функцию на основе ее имени, заданного строкой. Что-то вроде

public void callByName(String funcName){
   this.(funcName)();
}

Я немного искал лямбда-функции, но они не поддерживаются. Я думал о переходе на Reflection, но я немного новичок в программировании, поэтому я не очень знаком с предметом.

Весь этот вопрос был задан в моем классе Java-ООП, когда я начал программировать на GUI (Swing, SWT) и событиях. Я обнаружил, что использование object.addActionCommand() очень уродливо, потому что позже мне потребуется сделать Switch и поймать именно ту команду, которую я хотел.

Я бы предпочел сделать что-то вроде object.attachFunction(btn1_click), чтобы оно вызывало функцию btn1_click при возникновении щелчка по событию.

Ответы [ 6 ]

6 голосов
/ 31 мая 2010

В Java есть методы, а не функции. Разница в том, что у методов есть классы; вам нужно знать класс для вызова метода. Если это метод экземпляра, вам нужен экземпляр для его вызова, но OTOH означает, что вы можете легко найти метод:

public void callByName(Object obj, String funcName) throws Exception {
    // Ignoring any possible result
    obj.getClass().getDeclaredMethod(funcName).invoke(obj);
}

Обратите внимание, что существует лот потенциальных исключений из этого, и все становится более сложным, если вы хотите передать аргументы.

Если вы говорите о методе класса, то, что вы делаете, немного отличается:

public void callClassByName(Class cls, String funcName) throws Exception {
    // Ignoring any possible result
    cls.getDeclaredMethod(funcName).invoke(null);
}

Возможно, вы захотите исследовать, используя java.lang.reflect.Proxy.

2 голосов
/ 31 мая 2010

Следующий код вызовет открытый метод с заданным именем без аргумента:

public void callByName(String funcName) {
    try {
        Method method = getClass().getDeclaredMethod(funcName);
        method.invoke(this, new Object[] {});
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}
1 голос
/ 31 мая 2010

Этот вопрос задавался ранее. Смотри здесь

1 голос
/ 31 мая 2010

Вы можете использовать Class.getDeclaredMethod(), чтобы получить метод с определенным именем и параметрами, а затем вызвать возвращенный объект Method:

Method method = MyClass.class.getDeclaredMethod("methodName", Event.class, String.class);
Object retVal = method.invoke(someEvent, someString);
0 голосов
/ 31 мая 2010

Да, для этого можно использовать Reflection API, но я не думаю, что это способ для простой обработки событий кнопки. Лучше спросить, как это можно сделать элегантно в используемой вами графической среде (Swing, SWT ...), я уверен, что должен быть более простой способ, чем Reflection.

0 голосов
/ 31 мая 2010

Проверьте Class.forName (), чтобы получить определение класса для данного имени.

Если у вас есть интерфейс, содержащий метод, который вы хотите запустить, и класс реализует этот метод, вы можете просто создать экземпляр, привести его к интерфейсу и вызвать метод.

ЕслиВы не можете ничего предположить, использовать отражение в экземпляре класса, чтобы получить нужный метод, и вызывать его с необходимыми аргументами.В Sun Tutorial есть хороший раздел по отражению.

...