元注解(Meta-Annotations)详解
元注解(Meta-Annotations)详解
元注解是用于定义其他注解行为的注解,Java提供了5种核心元注解(Java 8新增@Repeatable
),以下是它们的详细说明:
1. @Target
:指定注解可应用的目标
-
作用:定义注解可以标注在哪些代码元素上(如类、方法、字段等)。意思就是说,限定注解只能出现在哪里。
-
取值:
ElementType
枚举的数组,常用值如下:ElementType 说明 TYPE
类、接口、枚举 FIELD
字段(包括枚举常量) METHOD
方法 PARAMETER
方法参数 CONSTRUCTOR
构造方法 LOCAL_VARIABLE
局部变量 ANNOTATION_TYPE
其他注解(元注解自身) PACKAGE
包声明 TYPE_PARAMETER
泛型类型参数(Java 8+) TYPE_USE
类型使用处(如泛型、强制转换,Java 8+)。作用于任意类型 -
示例:
@Target({ElementType.METHOD, ElementType.FIELD}) public @interface MyAnnotation {}
2. @Retention
:定义注解的生命周期
-
作用:控制注解在何时有效(源码、字节码、运行时)。
-
取值:
RetentionPolicy
枚举,可选值:RetentionPolicy 说明 SOURCE
注解仅保留在源码中(编译后丢弃),如 @Override
、@SuppressWarnings
。CLASS
注解保留到字节码文件,但运行时不可见(默认值)。 RUNTIME
注解保留到运行时,可通过反射读取(如Spring的 @Component
)。 -
示例:
@Retention(RetentionPolicy.RUNTIME) public @interface RuntimeAnnotation {}
3. @Documented
:将注解包含在Javadoc中
- 作用:标记注解是否应出现在生成的Javadoc文档中。
- 示例:
@Documented public @interface ApiDoc {String description(); }
- 使用
@ApiDoc
的类/方法,其Javadoc会显示该注解信息。
- 使用
4. @Inherited
:允许子类继承父类的注解
- 作用:仅对类注解有效,子类会自动继承父类使用的注解。
- 限制:不适用于方法/字段注解。
- 示例:
@Inherited @Retention(RetentionPolicy.RUNTIME) public @interface InheritableAnnotation {}@InheritableAnnotation public class Parent {}public class Child extends Parent {} // Child类自动继承@InheritableAnnotation
5. @Repeatable
(Java 8+):允许重复使用同一注解
- 作用:允许在同一位置多次使用同一注解(需配合容器注解)。
- 示例:
// 定义可重复注解 @Repeatable(Authorities.class) public @interface Authority {String role(); }// 容器注解 public @interface Authorities {Authority[] value(); }// 使用 @Authority(role = "admin") @Authority(role = "user") public class User {}
元注解的组合使用示例
@Target(ElementType.METHOD) // 注解用于方法
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
@Documented // 包含在Javadoc
public @interface Loggable {String module() default "default";boolean trackTime() default false;
}
常见问题与陷阱
@Inherited
不生效:- 仅对类注解有效,且子类继承的是类级别的注解,方法/字段注解不继承。
- 重复注解的容器注解:
- 使用
@Repeatable
时必须定义容器注解(如Authorities
),否则编译报错。
- 使用
- 默认生命周期为
CLASS
:- 若未指定
@Retention
,注解默认保留到字节码但运行时不可见。
- 若未指定
记忆方法
- 口诀:
目标(Target)定位置,保留(Retention)定生死;文档(Documented)显身手,继承(Inherited)传子孙。
- 比喻:
@Target
像标签的粘贴位置(如冰箱贴只能贴在冰箱上)。@Retention
像标签的持久性(便利贴易撕、胶带持久)。@Repeatable
像允许在同一位置贴多张相同标签。
实际应用场景
- 框架开发:Spring的
@Component
(@Target(TYPE)
+@Retention(RUNTIME)
)。 - API文档:Swagger的
@ApiOperation
(结合@Documented
)。 - 权限控制:自定义
@RequiresRole
(@Retention(RUNTIME)
+ 反射处理)。
掌握元注解的使用,是设计高效、灵活自定义注解的关键!