简体   繁体   中英

How to get the list of annotations of a class and its superclass

I'm writing a method supposed to retrieve all annotations of a specific method declaring class and its superclasses.

By using the method getAnnotations() on the declaring class, the resulting table contains only the declaring class annotations and the superclass annotations are ignored. If I remove the annotations of the declaring class, then the superclass annotation are present.

What am I missing here?

The simplified method retrieving the annotations :

public void check(Method invokedMethod) {
    for (Annotation annotation : invokedMethod.getDeclaringClass().getAnnotations()) {
        // Do something ...
    }
}

(All annotations I'm trying the get have the @Inherited annotation)

In case you need to process several annotations of the same type, the standard approach is does not work, because annotations are stored in a Map with annotation types as the key. (See more here ). Here is how I would work around this problem (just go through all super classes manually):

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

public class AnnotationReflectionTest {
    public static void main(String[] args) throws Exception {
        check(Class2.class.getMethod("num", new Class[0]));
    }

    public static void check(Method invokedMethod) {
        Class<?> type = invokedMethod.getDeclaringClass();
        while (type != null) {
            for (Annotation annotation : type.getDeclaredAnnotations()) {
                System.out.println(annotation.toString());
            }
            type = type.getSuperclass();
        }
    }
}

@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Annot1 {
    int num();
}

@Annot1(num = 5)
class Class1 {
    public int num() {
        return 1;
    }
}

@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Annot2 {
    String text();
}

@Annot2(text = "ttt")
class Class2 extends Class1 {
    public int num() {
        return super.num() + 1;
    }
}

What version of Java and what OS do you use?

I had to write a simple method with

private <A extends Annotation> A getAnnotationFromType(Class<?> classType, final Class<A> annotationClass) {
    
    while ( !classType.getName().equals(Object.class.getName()) ) {
        
        if ( classType.isAnnotationPresent(annotationClass)) {
            return classType.getAnnotation(annotationClass);
        }
        classType = classType.getSuperclass();
    }
    return null;
    
}
    

This might be obvious to most people, but if you came here looking for fields of a class and its superclasses , you can use

myClass.getFields()

to get all fields, also of superclasses, instead of

myClass.getDeclaredFields()

which only returns the fields of the class itself. Similarly for methods and constructors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM