2013-12-17 1 views
0

나는 프로젝트의 클래스와 메소드에 대한 "id"의 유일성을 검사하는 IdChecker 프로그램을 구현 중이다. IdChecker는 릴리스를 푸시하기 전에 프로젝트를 컴파일 할 때만 실행됩니다.클래스를 알고있을 때 메소드를 올바르게 호출하는 방법은 무엇입니까?

클래스의 경우 모든 클래스를 매핑해야하므로 MyClass.getField ("CLASS_ID")를 호출하면됩니다. getShort (MyClass.getField ("CLASS_ID")); 그런 다음 className과 classIdentifier가 포함 된 ClassWrapper를 만듭니다.

메소드의 경우 리플렉션을 사용하여 메소드에 로컬 인 변수에 액세스 할 수 없으므로 좀 더 복잡합니다 ...하지만 ... 내 프로젝트에서는 디버그 로그를 사용하여 모든 로그를 남깁니다. "진입 방법"및 "이탈 방안". 로컬 변수를 얻으려면 메소드를 호출하고이 로그 항목에서 마지막 항목 ("leave-the-method"로그 항목)을 내 logBuffer에서 읽으면 METHOD_ID가 표시됩니다.

내 문제

: 나는 IllegalArgumentException를 생성하는 클래스에 메소드를 호출 할 수 없습니다

... 나는 방법에 매개 변수를 전달할 필요가 없습니다 , 나는 단지 내가 할 수있는 그 (것)들을 호출 할 로그 항목을 생성하십시오.

private void getMethodsList() throws IllegalArgumentException, 
    IllegalAccessException, NoSuchFieldException, SecurityException { 
    final short METHOD_ID = 0x03; 
    /* Log-entering the method */ 
    mLogger.logDebug((byte) 1, METHOD_ID); 

    /* Create the MethodWrapper list corresponding 
     to each element of the ClassWrapper list */ 
    for(Class<?> clazz : mClasses) 
    { 
     /* Get the declared methods from each class */ 
     for(Method method : clazz.getDeclaredMethods()) 
     { 
      /* Get the name of the method */ 
      String newName = method.getName(); 
      short newIdentifier = 0; 
      try 
      { 
       method.invoke(clazz, new Object[]{null}); 
       /* Get the identifier of the class */ 
       newIdentifier = AbstractDebugLogger.mLastMethodID; 
      } 

     . 
     . 
     . 
+2

'Method # invoke (..)'의 javadoc을 읽으십시오. 그것은 인수로서 기대하는 것이 명백합니다. –

+2

이 경우에는 맞춤 주석을 사용하는 것이 더 정확할 것입니다 (예 :'@MethodId (0x03)'). –

답변

1

method.invoke (...)에는 실제로 메서드를 호출하는 데 사용할 수있는 인수 배열이 필요합니다. 이 경우 {null}을 지정하면 단일 객체를 허용하지만 다른 함수는 허용하지 않는 모든 함수에 사용할 수 있습니다. 임의의 함수를 호출하려면 함수가 필요 인수의 수에 매개 변수 목록의 길이와 일치해야합니다

method.invoke(..., new Object[method.getParameterTypes().length]) 

를이 여전히 몇 가지 문제가있다. 첫째, invoke의 첫 번째 매개 변수는 입력 한 클래스가 아니라 해당 클래스의 객체 (정적 메소드의 경우 null)입니다. 클래스의 생성자를 검색하여 해당 클래스의 인스턴스 메소드를 호출하기 전에 해당 클래스의 인스턴스를 생성해야합니다. 두 번째 문제는 원시 일 필요가있는 함수에서는 null이 될 수 없다는 점입니다. 매개 변수의 클래스를 점검하고 필요에 따라 null을 0 또는 false로 바꿀 수 있습니다. 세 번째로 가장 중요한 문제는 이렇게하기가 어렵다는 것입니다. 은 실제로 메서드 호출을 원하지 않습니다. 메서드에 대한 정보를 검색하려고합니다.이 경우 메서드 내부에 저장됩니다. 적절한 해결책은 주석과 함께 메소드에 첨부 된 정보를 저장하는 것입니다.

@Retention(RetentionPolicy.RUNTIME) 
@interface ID { 
    int value(); 
} 
... 
@ID(1337) 
void exampleMethod() { ... } 
... 
newIdentifier = method.getAnnotation(ID.class).value(); //returns 1337 for exampleMethod 
+0

대단히 감사합니다 !!!! – user3111783

관련 문제