You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取类上的所有父注解?以Test类获取SuperAnnotation为例

如何获取类上注解的父注解(元注解)

这个问题很典型——Java默认不会自动帮你获取注解上的元注解(也就是你说的“父注解”),因为注解之间的继承逻辑和类继承不一样:哪怕你给SubAnnotation加了@SuperAnnotation,直接调用Test.class.getAnnotations()也只会拿到SubAnnotation本身。不过我们可以手动遍历注解的元注解来解决这个问题,下面给你具体的实现方案:

基础解决方案:直接获取元注解

首先要明确:每个注解本身也是一个Class对象,所以可以通过annotation.annotationType()拿到注解的类型,再调用getAnnotations()获取它上面的所有元注解。修改你的测试代码如下:

import java.lang.annotation.Annotation;

@SubAnnotation
public class Test {
    public static void main(String args[]) {
        // 第一步:获取Test类上的所有直接注解
        Annotation[] classAnnotations = Test.class.getAnnotations();
        
        for (Annotation classAnnot : classAnnotations) {
            System.out.println("类上的直接注解:" + classAnnot);
            
            // 第二步:获取当前注解的元注解(即你要的SuperAnnotation)
            Annotation[] metaAnnotations = classAnnot.annotationType().getAnnotations();
            for (Annotation metaAnnot : metaAnnotations) {
                System.out.println("注解的元注解:" + metaAnnot);
            }
        }
    }
}

// 定义SuperAnnotation
@Retention(RetentionPolicy.RUNTIME)
public @interface SuperAnnotation {
}

// 定义SubAnnotation,标记了SuperAnnotation
@Retention(RetentionPolicy.RUNTIME)
@SuperAnnotation
public @interface SubAnnotation {
}

运行这段代码后,你会看到输出:

类上的直接注解:@SubAnnotation()
注解的元注解:@SuperAnnotation()
注解的元注解:@java.lang.annotation.Retention(value=RUNTIME)

这里除了SuperAnnotation,还会输出@Retention,因为它也是SubAnnotation的元注解。如果只想拿到自定义的元注解,可以加个判断过滤掉JDK自带的注解。

进阶方案:递归获取所有层级的元注解

如果你的注解体系更复杂(比如SuperAnnotation上面还有一层元注解),可以写一个递归方法来遍历所有层级的注解,避免遗漏:

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

@SubAnnotation
public class Test {
    public static void main(String args[]) {
        List<Annotation> allAnnotations = new ArrayList<>();
        
        // 先收集类上的直接注解
        Annotation[] classAnnotations = Test.class.getAnnotations();
        for (Annotation annot : classAnnotations) {
            collectAllAnnotations(annot, allAnnotations);
        }
        
        // 输出所有收集到的注解
        System.out.println("所有层级的注解:");
        for (Annotation annot : allAnnotations) {
            System.out.println(annot);
        }
    }

    // 递归收集所有注解及元注解
    private static void collectAllAnnotations(Annotation annotation, List<Annotation> result) {
        if (annotation == null || result.contains(annotation)) {
            return; // 避免循环引用,直接返回
        }
        result.add(annotation);
        
        // 获取当前注解的所有元注解,继续递归
        Annotation[] metaAnnotations = annotation.annotationType().getAnnotations();
        for (Annotation metaAnnot : metaAnnotations) {
            collectAllAnnotations(metaAnnot, result);
        }
    }
}

// 定义SuperAnnotation,假设它还有自己的元注解
@Retention(RetentionPolicy.RUNTIME)
@AnotherMetaAnnotation
public @interface SuperAnnotation {
}

@Retention(RetentionPolicy.RUNTIME)
public @interface AnotherMetaAnnotation {
}

@Retention(RetentionPolicy.RUNTIME)
@SuperAnnotation
public @interface SubAnnotation {
}

这个工具方法会把SubAnnotation、SuperAnnotation、AnotherMetaAnnotation以及它们的@Retention注解都收集起来,非常适合复杂的注解场景。

注意事项:@Inherited的局限性

这里要提醒你:Java的@Inherited注解只作用于类之间的继承——比如如果Test类继承了一个带有注解的父类,子类会继承父类的注解,但它不会让注解继承自己的元注解,所以不要指望用@Inherited来解决这个问题,必须手动遍历元注解。

内容的提问来源于stack exchange,提问作者Domi.Zhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:47:58