How to get annotations of a member variable?

JavaReflectionAnnotationsBeaninfo

Java Problem Overview


I want to know a class's some member variable's annotations , I use BeanInfo beanInfo = Introspector.getBeanInfo(User.class) to introspect a class , and use BeanInfo.getPropertyDescriptors() , to find specific property , and use Class type = propertyDescriptor.getPropertyType() to get the property's Class .

But I don't know how to get the annotations added to the member variable ?

I tried type.getAnnotations() , and type.getDeclaredAnnotations() , but both return the Class's annotations , not what I want . For example :

class User 
{
  @Id
  private Long id;
  
  @Column(name="ADDRESS_ID")
  private Address address;

  // getters , setters
}

@Entity
@Table(name = "Address")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
class Address 
{
  ...
}

I want to get the address's annotation : @Column , not class Address's annotations (@Entity , @Table , @Cache) . How to achieve it ? Thanks.

Java Solutions


Solution 1 - Java

for(Field field : cls.getDeclaredFields()){
  Class type = field.getType();
  String name = field.getName();
  Annotation[] annotations = field.getDeclaredAnnotations();
}

See also: http://docs.oracle.com/javase/tutorial/reflect/class/classMembers.html

Solution 2 - Java

Everybody describes issue with getting annotations, but the problem is in definition of your annotation. You should to add to your annotation definition a @Retention(RetentionPolicy.RUNTIME):

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation{
	int id();
}

Solution 3 - Java

If you need know if a annotation specific is present. You can do so:

	Field[] fieldList = obj.getClass().getDeclaredFields();
		
		boolean isAnnotationNotNull, isAnnotationSize, isAnnotationNotEmpty;
		
		for (Field field : fieldList) {
			
			//Return the boolean value
			isAnnotationNotNull = field.isAnnotationPresent(NotNull.class);
			isAnnotationSize = field.isAnnotationPresent(Size.class);
			isAnnotationNotEmpty = field.isAnnotationPresent(NotEmpty.class);
  
		}

And so on for the other annotations...

I hope help someone.

Solution 4 - Java

You have to use reflection to get all the member fields of User class, iterate through them and find their annotations

something like this:

public void getAnnotations(Class clazz){
    for(Field field : clazz.getDeclaredFields()){
        Class type = field.getType();
        String name = field.getName();
        field.getDeclaredAnnotations(); //do something to these
    }
}

Solution 5 - Java

You can get annotations on the getter method:

propertyDescriptor.getReadMethod().getDeclaredAnnotations();

Getting the annotations of a private field seems like a bad idea... what if the property isn't even backed by a field, or is backed by a field with a different name? Even ignoring those cases, you're breaking abstraction by looking at private stuff.

Solution 6 - Java

package be.fery.annotation;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.PrePersist;

@Entity
public class User {
	@Id
	private Long id;
	
	@Column(name = "ADDRESS_ID")
	private Address address;
	
	@PrePersist
	public void doStuff(){
		
	}
}

And a testing class:

    package be.fery.annotation;

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

public class AnnotationIntrospector {

	public AnnotationIntrospector() {
		super();
	}

	public Annotation[] findClassAnnotation(Class<?> clazz) {
		return clazz.getAnnotations();
	}

	public Annotation[] findMethodAnnotation(Class<?> clazz, String methodName) {

		Annotation[] annotations = null;
		try {
			Class<?>[] params = null;
			Method method = clazz.getDeclaredMethod(methodName, params);
			if (method != null) {
				annotations = method.getAnnotations();
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		return annotations;
	}

	public Annotation[] findFieldAnnotation(Class<?> clazz, String fieldName) {
		Annotation[] annotations = null;
		try {
			Field field = clazz.getDeclaredField(fieldName);
			if (field != null) {
				annotations = field.getAnnotations();
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}
		return annotations;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		AnnotationIntrospector ai = new AnnotationIntrospector();
		Annotation[] annotations;
		Class<User> userClass = User.class;
		String methodDoStuff = "doStuff";
		String fieldId = "id";
		String fieldAddress = "address";

		// Find class annotations
		annotations = ai.findClassAnnotation(be.fery.annotation.User.class);
		System.out.println("Annotation on class '" + userClass.getName()
				+ "' are:");
		showAnnotations(annotations);

		// Find method annotations
		annotations = ai.findMethodAnnotation(User.class, methodDoStuff);
		System.out.println("Annotation on method '" + methodDoStuff + "' are:");
		showAnnotations(annotations);

		// Find field annotations
		annotations = ai.findFieldAnnotation(User.class, fieldId);
		System.out.println("Annotation on field '" + fieldId + "' are:");
		showAnnotations(annotations);

		annotations = ai.findFieldAnnotation(User.class, fieldAddress);
		System.out.println("Annotation on field '" + fieldAddress + "' are:");
		showAnnotations(annotations);

	}

	public static void showAnnotations(Annotation[] ann) {
		if (ann == null)
			return;
		for (Annotation a : ann) {
			System.out.println(a.toString());
		}
	}

}

Hope it helps...

;-)

Solution 7 - Java

My way

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

public class ReadAnnotation {
    private static final Logger LOGGER = LoggerFactory.getLogger(ReadAnnotation.class);
    
    public static boolean hasIgnoreAnnotation(String fieldName, Class entity) throws NoSuchFieldException {
        return entity.getDeclaredField(fieldName).isAnnotationPresent(IgnoreAnnotation.class);
    }

    public static boolean isSkip(PropertyDescriptor propertyDescriptor, Class entity) {
        boolean isIgnoreField;
        try {
            isIgnoreField = hasIgnoreAnnotation(propertyDescriptor.getName(), entity);
        } catch (NoSuchFieldException e) {
            LOGGER.error("Can not check IgnoreAnnotation", e);
            isIgnoreField = true;
        }
        return isIgnoreField;
    }

    public void testIsSkip() throws Exception {
        Class<TestClass> entity = TestClass.class;
        BeanInfo beanInfo = Introspector.getBeanInfo(entity);

        for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
            System.out.printf("Field %s, has annotation %b", propertyDescriptor.getName(),  isSkip(propertyDescriptor, entity));
        }
    }

}

Solution 8 - Java

Or you could try this

try {
    BeanInfo bi = Introspector.getBeanInfo(User.getClass());
    PropertyDescriptor[] properties = bi.getPropertyDescriptors();
    for(PropertyDescriptor property : properties) {
        //One way
        for(Annotation annotation : property.getAnnotations()){
            if(annotation instanceof Column) {
                String string = annotation.name();
            }
        }
        //Other way
        Annotation annotation = property.getAnnotation(Column.class);
        String string = annotation.name();
    }
}catch (IntrospectonException ie) {
    ie.printStackTrace();
}

Hope this will help.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsmallufoView Question on Stackoverflow
Solution 1 - JavaLaurence GonsalvesView Answer on Stackoverflow
Solution 2 - JavaSaturnimView Answer on Stackoverflow
Solution 3 - JavaMarcelo RebouçasView Answer on Stackoverflow
Solution 4 - JavamkoryakView Answer on Stackoverflow
Solution 5 - JavaLaurence GonsalvesView Answer on Stackoverflow
Solution 6 - JavaPhilippe FeryView Answer on Stackoverflow
Solution 7 - JavaGleb BelyaevView Answer on Stackoverflow
Solution 8 - JavaMaxenceView Answer on Stackoverflow