How to check if the parameter of the current method has annotation and retrieve the value of this parameter in Java?

Consider this code:

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

I want to check if the method has @Foo annotation and receives an argument or throws an exception if @Foo @Foo not found.

My current approach is to get the current method first and then repeat 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) { /* ... */ } } } } 

Is this the right approach or is there a better one? What does the code look like inside the forach loop? I'm not sure if I realized that getParameterAnnotations really coming back ...

+8
java reflection methods class annotations
source share
3 answers

Outer loop

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

must use an explicit counter, otherwise you do not know which 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]); } } } 

Also make sure your annotation type is annotated with @Retention(RetentionPolicy.RUNTIME)

From your question it is not clear what you are trying to do. We agree with the difference of formal parameters with the actual arguments:

 void foo(int x) { } { foo(3); } 

where x is the parameter and 3 is the argument?

It is not possible to get method arguments through reflection. If at all possible, you will have to use the sun.unsafe package. I can not tell you about this.

+6
source share

getParameterAnnotations returns an array with a length equal to the number of method parameters. Each element in this array contains an array of annotations for this parameter.
So, getParameterAnnotations()[2][0] contains the first ( [0] ) annotation of the third ( [2] ) parameter.

If you only need to check if at least one parameter contains an annotation of a certain type, the method may look like this:

 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; } 
+4
source share

If you are looking for method annotations, you probably want method.getAnnotations() or method.getDeclaredAnnotations() .

Calling method.getParameterAnnotations() gives you annotations of the formal parameters of the method, not the method itself.

Looking back at the title of the question, I suspect that you are looking for annotations for parameters that I did not read in the content of the question. In this case, your code looks fine.

See Javadoc Method and AnnotatedElement Javadoc .

+3
source share

All Articles