Использование отражения Java для создания метода eval () - PullRequest
5 голосов
/ 12 апреля 2010

У меня есть вопрос об отражении Я пытаюсь иметь какой-то метод eval (). Так что я могу позвонить, например:

eval("test('woohoo')");

Теперь я понимаю, что в Java нет метода eval, но есть отражение. Я сделал следующий код:

String s = "test";
Class cl = Class.forName("Main");
Method method = cl.getMethod(s, String.class);
method.invoke(null, "woohoo");

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

Я не знаю, что это за параметры (не только String.class). Но как это возможно? как я могу получить типы параметров метода? Я знаю следующий метод:

Class[] parameterTypes = method.getParameterTypes();

Но это вернет parameterTypes только что выбранного метода! со следующим утверждением:

Method method = cl.getMethod(s, String.class);

Любая помощь будет принята с благодарностью!

Ответы [ 4 ]

15 голосов
/ 12 апреля 2010

Вам нужно будет вызвать Class.getMethods() и перебрать их в поисках правильной функции.

For (Method method : clazz.getMethods()) {
  if (method.getName().equals("...")) {
    ...
  }
}

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

getMethods() возвращает все открытые методы в классе, в том числе из суперклассов. Альтернатива - Class.getDeclaredMethods(), которая возвращает все методы в этом классе только .

5 голосов
/ 12 апреля 2010

Вы можете перебрать все методы класса, используя:

cls.getMethods(); // gets all public methods (from the whole class hierarchy)

или

cls.getDeclaredMethods(); // get all methods declared by this class

.

for (Method method : cls.getMethods()) {
    // make your checks and calls here
}
2 голосов
/ 12 апреля 2010

Хорошо, спасибо всем, кто ответил на мой вопрос, вот окончательное решение:

import java.lang.reflect.Method;
public class Main {
   public static void main(String[] args){
      String func = "test";
      Object arguments[] = {"this is ", "really cool"};
      try{
         Class cl = Class.forName("Main");
         for (Method method : cl.getMethods()){
            if(method.getName().equals(func)){
               method.invoke(null, arguments);
            }
          }
       } catch (Exception ioe){
          System.out.println(ioe);
       }
    }
  public static void test(String s, String b){
     System.out.println(s+b);
  }
}
2 голосов
/ 12 апреля 2010

Вы можете использовать getMethods(), который возвращает массив всех методов класса. Внутри цикла вы можете проверить параметры каждого метода.

for(Method m : cl.getMethods()) {
   Class<?>[] params = m.getParameterTypes();
   ...
}

В противном случае вы можете использовать getDelcaredMethods(), что позволит вам «видеть» приватные методы (но не унаследованные). Обратите внимание, что если вы хотите вызвать закрытые методы, вы должны сначала применить к нему setAccessible (логический флаг) :

for(Method m : cl.getDelcaredMethods()) {
   m.setAccessible(true);
   Class<?>[] params = m.getParameterTypes();
   ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...