Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get annotation class name, attribute values using reflection

I know if we know the annotation class, we can easily get the specific annotation and access its attribute. For example:

field.getAnnotation(Class<T> annotationClass)  

Which will return a reference of specific annotation interface, so you can easily access its values.

My question is if I have no pre knowledge about the particular annotations class. I just want to use reflection to get all the annotation class name and their attributes at run-time for the purpose of dumping the class information for example as a JSON file. How can I do it in an easy way.

Annotation[] field.getAnnotations(); 

This method will only return dynamic proxies of the annotation interfaces.

like image 259
Jianwu Chen Avatar asked Dec 03 '13 21:12

Jianwu Chen


People also ask

How do you find the class name in reflection?

Getting class name using reflection If you want to get the class name using the instance of the Class. As you can see using the method getName() gives you the fully qualified name whereas getSimpleName() method gives you only the class name.

How do you find a class annotation?

The getAnnotation() method of java. lang. Class class is used to get the annotation of the specified annotation type, if such an annotation is present in this class. The method returns that class in the form of an object.

Can Java reflection API access private fields and methods of a class?

Despite the common belief it is actually possible to access private fields and methods of other classes via Java Reflection. It is not even that difficult. This can be very handy during unit testing.


2 Answers

Contrary to what one might expect, the elements of an annotation are not attributes - they are actually methods that return the provided value or a default value.

You have to iterate through the annotations' methods and invoke them to get the values. Use annotationType() to get the annotation's class, the object returned by getClass() is just a proxy.

Here is an example which prints all elements and their values of the @Resource annotation of a class:

@Resource(name = "foo", description = "bar") public class Test {      public static void main(String[] args) throws Exception {          for (Annotation annotation : Test.class.getAnnotations()) {             Class<? extends Annotation> type = annotation.annotationType();             System.out.println("Values of " + type.getName());              for (Method method : type.getDeclaredMethods()) {                 Object value = method.invoke(annotation, (Object[])null);                 System.out.println(" " + method.getName() + ": " + value);             }         }      } } 

Output:

Values of javax.annotation.Resource  name: foo  type: class java.lang.Object  lookup:   description: bar  authenticationType: CONTAINER  mappedName:   shareable: true 

Thanks to Aaron for pointing out the you need to cast the null argument to avoid warnings.

like image 173
kapex Avatar answered Sep 28 '22 04:09

kapex


Just to follow up on the answer above (I don't have enough rep to reply to it):

method.invoke(annotation, null) 

should be changed to the following, otherwise it throws an exception:

method.invoke(annotation, (Object[])null) or method.invoke(annotation, new Object[0]) 
like image 41
Aaron Avatar answered Sep 28 '22 04:09

Aaron