问题描述
考虑这个代码:
public example(String s, int i, @Foo Bar bar) {
/* ... */
}
我想检查该方法是否有注释 @Foo
并获取参数或在找不到 @Foo
注释时抛出异常.
I want to check if the method has an annotation @Foo
and get the argument or throw an exception if no @Foo
annotation is found.
我目前的做法是先获取当前方法,然后遍历参数注解:
My current approach is to first get the current method and then iterate through the parameter annotations:
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
实际返回的内容...
Is this the right approach or is there a better one?How would the code inside the forach loop look like? I'm not sure if I have understood the what getParameterAnnotations
actually returns...
推荐答案
外部 for 循环
for (Annotation[] annotations : paramAnnotations) {
...
}
应该使用显式计数器,否则你不知道你现在正在处理什么参数
should use an explicit counter, otherwise you don't know what parameter you are processing right now
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)
Also make sure your annotation type is annotated with @Retention(RetentionPolicy.RUNTIME)
从您的问题来看,并不完全清楚您要做什么.我们同意形式参数与实际参数的区别:
From your question it is not entirely clear what you are trying to do. We agree on the difference of formal parameters vs. actual arguments:
void foo(int x) { }
{ foo(3); }
其中 x
是参数,3
是参数?
where x
is a parameter and 3
is an argument?
无法通过反射获取方法的参数.如果可能的话,您将不得不使用 sun.unsafe
包.不过我不能告诉你太多.
It is not possible to get the arguments of methods via reflection. If it is possible at all, you would have to use the sun.unsafe
package. I can't tell you much about that though.
这篇关于如何检查当前方法的参数是否有注释并在 Java 中检索该参数值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!