如何在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实际返回的内容…

外部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包。但是我不能告诉你太多。

如果您正在寻找方法上的注释,您可能需要method.getAnnotations()method.getDeclaredAnnotations()

method.getParameterAnnotations()调用给出了方法形式参数的注释,而不是方法本身的注释。

回头看题目,我怀疑你是在寻找关于参数的注释,我没有在题目的内容中看到。如果是这样的话,你的代码看起来很好。

参见Method Javadoc和AnnotatedElement Javadoc

getParameterAnnotations返回的数组长度等于方法参数的个数。数组中的每个元素都包含一个关于该参数的注释数组。
因此,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;
}

相关内容

  • 没有找到相关文章

最新更新