java元注解共6个:@target限定作用位置,@retention控制生命周期(source/class/runtime),@documented使注解出现在javadoc中,@inherited支持类级注解继承,@repeatable允许同一位置重复使用注解,@native标识native字段。

Java自定义注解不是简单打个标签,而是通过元注解精确控制注解的行为边界——什么时候生效、用在哪儿、是否被文档收录、能否被继承。设计得当的注解,本身就是一种轻量级契约。
明确作用范围:@Target 是注解的“使用说明书”
不加 @Target 的注解默认只能用于类、接口、枚举声明(ElementType.TYPE),一旦用在方法或字段上会编译报错。实际开发中必须显式限定:
- 日志注解通常只允许标注方法:@Target(ElementType.METHOD)
- 权限校验注解可能需同时支持方法和类:@Target({ElementType.METHOD, ElementType.TYPE})
- 字段校验注解必须指定 ElementType.FIELD,否则无法在反射中获取到目标字段
- 若想让注解可用于泛型类型(如 List),需额外加上 ElementType.TYPE_USE
决定运行时机:@Retention 决定注解“活多久”
绝大多数业务场景需要在运行时读取注解,所以 RUNTIME 是最常用选项;但并非所有注解都需要走到 JVM 阶段:
- 编译期检查类注解(如禁止某方法被调用)可用 @Retention(RetentionPolicy.SOURCE),不进 class 文件,零运行开销
- 某些框架级注解(如 Lombok)依赖 CLASS 阶段,由注解处理器生成代码,但不参与运行时逻辑
- RUNTIME 注解必须配合反射使用,例如 Method.getAnnotation(MyLog.class),这是 Spring AOP 和 Hibernate Validator 的底层基础
增强可维护性:@Documented 和 @Inherited 的实用价值
这两个元注解常被忽略,但在团队协作和继承体系中起关键作用:
- @Documented 让 javadoc 命令自动把注解声明写入 API 文档,调用方一眼看到 “该方法需携带 @Transactional”
- @Inherited 仅对类级别注解有效,且子类必须是直接继承(非实现接口),适合定义统一行为策略,比如父类标记 @Auditable,子类自动启用操作审计
- 注意:@Inherited 不作用于方法或字段,即使父类方法有 @Cacheable,子类重写后不会自动继承该注解
支持重复使用:@Repeatable 解决多实例需求
Java 8 之前,同一位置只能声明一个同类型注解;@Repeatable 让它变得自然:
- 定义 @Repeatable(Permissions.class) public @interface Permission { … }
- 配套定义容器注解 @interface Permissions { Permission[] value(); }
- 之后可在方法上写多个 @Permission(role="ADMIN") @Permission(role="EDITOR")
- 反射获取时,直接调用 method.getAnnotationsByType(Permission.class),无需手动解析容器
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











