2010-04-12 6 views
5

리플렉션에 대한 질문이 있습니다 어떤 종류의 eval() 메소드를 사용하려고합니다. 그래서 예를 들어 호출 할 수 있습니다 자바 리플렉션을 사용하여 eval() 메소드 만들기

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

지금 내가 이해 자바에는 평가 방법이 없지만 반사가있다. 다음 코드를 만들었습니다 :

이것은 완벽하게 작동합니다 (물론 try, catch 블록이이 코드 주위에 있음). 테스트 메소드를 실행합니다. 그러나 나는 모두 다른 매개 변수를 가진 여러 메소드를 호출하려고합니다.

매개 변수가 무엇인지 알지 못합니다 (String.class뿐 아니라). 그러나 이것이 어떻게 가능할까요? 어떻게 메서드의 매개 변수 형식을 얻을 수 있습니까?

Class[] parameterTypes = method.getParameterTypes(); 

하지만 난 그냥 선택한 방법의 parameterTypes와를 반환합니다 나는 다음과 같은 방법을 알아! 다음 진술과 함께 :

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

어떤 도움을 주실 수 있습니까?

+0

평가 후면 방법은 어쩌면 어떻게 [JRuby를 (HTTP 볼 수 있었다, 루비의 평가처럼 보이는 : // 케나. co.kr/projects/jruby/sources)가 수행합니다. – JRL

답변

15

당신은 Class.getMethods()를 호출하고 올바른 기능을 찾고 그들을 통해 반복해야합니다.

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

동일한 이름과 다른 매개 변수 유형 (즉, 메서드 이름이 오버로드 됨)이 여러 가지 메서드가있을 수 있습니다.

getMethods()은 수퍼 클래스의 공개 메소드를 포함하여 클래스의 모든 public 메소드를 리턴합니다. 대안은 Class.getDeclaredMethods()이며, 해당 클래스의 모든 메소드를 반환합니다. . 여기에 최종 솔루션을 내 질문에 대답하는 모든 사람들에게

+0

너희들은 빨리 빨리 달릴거야! .. : P forxs for the help!! 다음 코드는 완벽하게 작동한다! : Class cl = Class.forName ("Main"); (메서드 메서드 : cl.getMethods()) { if (method.getName(). equals ("test")) { 클래스 [] parameterTypes = method.getParameterTypes(); method.invoke (null, "this is", "so cool!"); } } – heldopslippers

+0

(누구든지이 스타일에 도움이 될 수 있습니까?) (미안) – heldopslippers

+0

스타일이란 무엇을 의미합니까? –

5

당신이 할 수있는 사용하여 클래스의 모든 방법을 통해 루프 :

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

당신은 클래스의 모든 메소드의 배열을 반환 getMethods()를 사용할 수 있습니다. 루프 내에서 각 방법의 매개 변수를 검사 할 수 있습니다.

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

그렇지 않으면 당신은 당신이 개인 방법 (그러나 상속되지 방법) "를 참조하십시오"할 수 getDelcaredMethods()를 사용할 수 있습니다. 당신이 개인 메소드를 호출 할 경우 처음에 setAccessible(boolean flag)를 적용해야합니다 :

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

확인 thanxs :

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

이 코드의 문제점은 견고하지 않다는 것입니다. 'test'의 시그니처를 다양하게 변경하면 예외가 발생합니다. 예 : 메소드가'static'이 아닌 경우, args의 수가 다른 경우 메소드가 표시되지 않으면 args의 유형이 다릅니다. –

+0

예, 맞습니다.하지만 다른 방법은 없습니다. 문자열에서 함수를 호출 할 수 있어야합니다 (Java 프로그램에 대한 소켓 연결을 설정하고 적절한 메서드 이름과 인수가있는 json을 보낼 수 있어야하기 때문입니다). 내가 처리하면 내 예외 처리 및 좋은 unittests 나는 그것이 충분히 강력 할 것이라고 생각한다 (또는 나는 희망한다 : P). – heldopslippers

관련 문제