2011-08-29 22 views
8

考慮以下代碼:如何檢查當前方法的參數是否有註釋並在Java中檢索該參數值?

public example(String s, int i, @Foo Bar bar) { 
    /* ... */ 
} 

我要檢查,如果該方法有一個註釋@Foo並獲得參數,或者如果沒有@Foo註解中找到拋出異常。

我目前的做法是,先獲取當前方法,然後通過參數註釋迭代:

import java.lang.annotation.Annotation; 
import java.lang.reflect.Method; 

class Util { 

    private Method getCurrentMethod() { 
     try { 
      final StackTraceElement[] stes = Thread.currentThread().getStackTrace(); 
      final StackTraceElement ste = stes[stes.length - 1]; 
      final String methodName = ste.getMethodName(); 
      final String className = ste.getClassName(); 
      final Class<?> currentClass = Class.forName(className); 
      return currentClass.getDeclaredMethod(methodName); 
     } catch (Exception cause) { 
      throw new UnsupportedOperationException(cause); 
     } 
    } 

    private Object getArgumentFromMethodWithAnnotation(Method method, Class<?> annotation) { 
     final Annotation[][] paramAnnotations = method.getParameterAnnotations();  
      for (Annotation[] annotations : paramAnnotations) { 
       for (Annotation an : annotations) { 
        /* ... */ 
       } 
      } 
    } 

} 

這是正確的做法還是有一個更好? forach循環內的代碼將如何顯示?我不確定我是否瞭解getParameterAnnotations實際返回的內容...

+0

我看不出有什麼錯,你已經 – skaffman

+0

+1因爲沒有執行'new Exception()。getStackTrace()' – Cephalopod

回答

6

外for循環

for (Annotation[] annotations : paramAnnotations) { 
    ... 
} 

應該使用一個明確的反擊,否則你不知道你正在處理什麼參數,現在

final Annotation[][] paramAnnotations = method.getParameterAnnotations(); 
final Class[] paramTypes = method.getParameterTypes(); 
for (int i = 0; i < paramAnnotations.length; i++) { 
    for (Annotation a: paramAnnotations[i]) { 
     if (a instanceof Foo) { 
      System.out.println(String.format("parameter %d with type %s is annotated with @Foo", i, paramTypes[i]); 
     } 
    } 
} 

另外,還要確保你的註釋類型都被註解@Retention(RetentionPolicy.RUNTIME)

從你的問題,它不是完全清楚你想要做什麼。我們同意在正式參數與實際參數的區別:

void foo(int x) { } 

{ foo(3); } 

其中x是一個參數,3一種說法?

不可能通過反射來獲取方法的參數。如果可能的話,你將不得不使用sun.unsafe包。雖然我不能告訴你很多。

+0

是的,我想獲得用'@ Foo'註釋的實際參數。 – soc

+0

您應該爲此創建一個明確的問題,因爲它在(不相關的)註釋內容之間丟失。 – Cephalopod

3

如果您正在尋找關於該方法的註釋,那麼您可能需要method.getAnnotations()method.getDeclaredAnnotations()

method.getParameterAnnotations()調用爲您提供有關方法形式參數的註釋,而不是方法本身。

回頭看問題標題,我懷疑你尋找關於參數的註釋,我沒有在問題的內容中讀到。如果是這樣的話,你的代碼看起來很好。

請參閱Method JavadocAnnotatedElement Javadoc

4

getParameterAnnotations返回一個長度等於方法參數數量的數組。該數組中的每個元素都包含該參數的數組annotations
因此,getParameterAnnotations()[2][0]包含第三個([2])參數的第一個([0])註釋。

如果你只需要檢查,如果至少一個參數包含特定類型的標註,該方法看起來是這樣的:

private boolean isAnyParameterAnnotated(Method method, Class<?> annotationType) { 
    final Annotation[][] paramAnnotations = method.getParameterAnnotations();  
    for (Annotation[] annotations : paramAnnotations) { 
     for (Annotation an : annotations) { 
      if(an.annotationType().equals(annotationType)) { 
       return true; 
      } 
     } 
    } 
    return false; 
} 
相關問題