【问题标题】:How to get the list of annotations of a class and its superclass如何获取类及其超类的注释列表
【发布时间】:2015-12-04 17:03:47
【问题描述】:

我正在编写一个方法,该方法应该检索声明类及其超类的特定方法的所有注释。

通过在声明类上使用方法getAnnotations(),结果表只包含声明类注解,忽略超类注解。 如果我删除了声明类的注解,那么超类注解就存在了。

我在这里错过了什么?

检索注释的简化方法:

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

(我尝试获取的所有注释都有@Inherited 注释)

【问题讨论】:

    标签: java inheritance reflection annotations


    【解决方案1】:

    如果您需要处理多个相同类型的注解,标准方法是行不通的,因为注解存储在Map 中,注解类型作为键。 (查看更多here)。以下是我将如何解决这个问题(只需手动浏览所有超类):

    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;
        }
    }
    

    您使用什么版本的 Java 和什么操作系统?

    【讨论】:

    • 嗨,谢谢你的回答,我在 mac os X 上使用 java 8。你的代码和我的很相似,我不太理解这种行为......我会看看我一回家就再来一次。
    • 似乎是解决我的问题的好方法。感谢您的宝贵时间!
    【解决方案2】:

    我不得不写一个简单的方法

    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;
        
    }
        
    

    【讨论】:

      【解决方案3】:

      这对大多数人来说可能很明显,但如果你来这里寻找fields of a class and its superclasses,你可以使用

      myClass.getFields()
      

      获取所有字段,包括超类,而不是

      myClass.getDeclaredFields()
      

      它只返回类本身的字段。方法和构造函数也是如此。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多