java元注解是定义注解行为的“说明书”,共五个:@target指定作用位置,@retention控制生命周期(runtime才可反射读取),@documented使注解出现在javadoc中,@inherited实现类继承性,@repeatable支持重复使用。

Java元注解是定义注解的“说明书”,不是直接用在业务代码上的标签,而是用来约束自定义注解本身的行为。想让自定义注解真正起作用,必须正确配置这五个元注解——缺一不可,配错一个就可能导致注解失效、反射读不到、子类不继承或文档不生成。
@Target:明确注解能贴在哪里
它规定了你的注解允许修饰哪些程序元素。不加@Target,注解默认只能用于类、接口、枚举类型(即ElementType.TYPE),其他地方会编译报错。
- 常见取值包括:ElementType.METHOD(方法)、ElementType.FIELD(字段)、ElementType.PARAMETER(参数)、ElementType.TYPE(类/接口/枚举)
- 支持多个位置:写成
@Target({ElementType.METHOD, ElementType.TYPE}) - 典型错误:想给方法参数加注解,却只声明了
@Target(ElementType.METHOD),结果参数上使用时报错
@Retention:决定注解活到什么时候
这是运行时注解能否被反射读取的关键。很多开发者写了注解却拿不到,八成是忘了设为RUNTIME。
- RUNTIME:注解保留在class文件中,并在运行时可通过反射获取(如Spring、MyBatis依赖此模式)
- CLASS:默认值,仅保留在class文件,JVM加载时不保留,反射读不到
- SOURCE:只在源码阶段存在,编译后彻底丢弃(如@Override就是SOURCE级)
- 必须显式声明:
@Retention(RetentionPolicy.RUNTIME),否则无法在运行期解析
@Documented:让注解出现在API文档里
加了它,Javadoc工具生成文档时,会把该注解及其说明一起输出。对公共SDK或框架开发者特别重要。
- 不加@Documented,即使注解用了,Javadoc里也完全看不到它的痕迹
- 它不影响功能,纯属提升可读性和协作体验
- 常与@Retention(RUNTIME)搭配使用,形成“可读+可用”的完整注解
@Inherited 和 @Repeatable:解决两个特定场景
@Inherited让注解具备“遗传性”:父类加了这个注解,子类自动拥有(仅对类生效,对方法/字段无效);@Repeatable则突破Java语法限制,允许同一位置重复使用同一个注解。
- @Inherited示例:全局权限配置注解
@GlobalAuth(level = "ADMIN")加在父Service上,子类无需重复声明 - @Repeatable需配合容器注解使用,例如:
@Roles("USER") @Roles("ADMIN")要求先定义@Repeatable(RolesContainer.class) - 两者都不是必需项,但一旦业务需要继承性或多次标记,就必须提前设计好
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











