保留策略与目标类型
选择 SOURCE、CLASS 或 RUNTIME 保留策略,并使用 @Target 限制目标元素
保留策略与目标类型 是 CoddyKit 上的免费 Java Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。
三种保留策略
SOURCE:由编译器丢弃(仅对 APT 有用)。CLASS:写入 .class 文件,但在运行时不可用。RUNTIME:可通过反射使用。大多数框架注解使用 RUNTIME。
SOURCE 保留:仅限编译时
SOURCE 注解会由注解处理器处理,然后被丢弃。@Override 和 @SuppressWarnings 都是 SOURCE 注解:它们会通知编译器,但不会出现在 .class 文件中。
@Retention(RetentionPolicy.SOURCE)
public @interface GenerateBuilder {}
// APT generates a Builder class when it sees @GenerateBuilder
// The annotation itself disappears from the compiled outputCLASS 保留:字节码分析
CLASS 注解会包含在 .class 文件中,供字节码分析工具(PMD、FindBugs、ASM)使用,但不能在运行时通过反射读取。
@Retention(RetentionPolicy.CLASS)
public @interface ThreadSafe {}
// Visible in bytecode, invisible to Class.getAnnotation() at runtimeRUNTIME 保留:反射处理
RUNTIME 注解会一直保留到运行时,并且可以使用 getAnnotation() 读取。Spring、JUnit、Jackson 和 Hibernate 都使用 RUNTIME 保留策略。
@Retention(RetentionPolicy.RUNTIME)
public @interface Route {
String path();
String method() default "GET";
}
// At runtime:
Route r = handler.getClass().getMethod("handle").getAnnotation(Route.class);
System.out.println(r.path()); // e.g. "/users"@Target:限制应用位置
@Target 使用 ElementType 常量限制注解可以出现的位置。如果将注解应用于不允许的元素,编译时就会产生错误。
import static java.lang.annotation.ElementType.*;
@Target({METHOD, CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface Measured {}所有 ElementType 值
完整列表:TYPE(类/接口/枚举)、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE、TYPE_PARAMETER(泛型类型参数)、TYPE_USE(任意类型使用位置)。
// TYPE_USE: annotate any type reference
@NotNull String name;
List<@NonNull String> items;
public @Valid User createUser(@NotNull String name) { ... }TYPE 与 TYPE_USE
TYPE 适用于类、接口和枚举声明。TYPE_USE(Java 8 及更高版本)适用于类型的任意使用位置,包括泛型、类型转换和 extends 子句,从而支持类型级别的空安全注解。
@Target(ElementType.TYPE_USE)
@interface NonNull {}
// Can be applied to:
List<@NonNull String> list;
@NonNull String result = (@NonNull String) obj;组合使用 Target 和 Retention
大多数实用的框架注解会将 RUNTIME 保留策略与特定目标结合使用。例如,可以定义一个仅应用于字段的验证注解。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Range {
int min() default 0;
int max() default Integer.MAX_VALUE;
}使用 @Inherited 继承注解
@Inherited 是一种元注解,会使类级别的注解被子类继承。它对方法或字段注解没有影响。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Framework {}
@Framework class Base {}
class Child extends Base {} // @Framework visible on Child too@Documented:包含在 Javadoc 中
应用 @Documented 后,注解会出现在带注解元素所生成的 Javadoc 中。如果不使用它,注解就不会显示在 API 文档中。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Auditable {
String description() default "";
}在运行时读取保留信息
您可以在注解类对象上使用 getAnnotation(Retention.class),检查注解类型本身的保留策略。
Retention r = Retry.class.getAnnotation(Retention.class);
System.out.println(r.value()); // RUNTIME, CLASS, or SOURCE快速检查
哪个 ElementType 涵盖类、接口和枚举声明?
回顾
编译时工具使用 SOURCE,字节码分析使用 CLASS,反射框架使用 RUNTIME。使用 @Target 限制应用范围,防止误用。为 API 注解添加 @Documented,为类层次结构注解添加 @Inherited。
常见问题解答
「保留策略与目标类型」课时是免费的吗?
是的 — 「保留策略与目标类型」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。
「保留策略与目标类型」这节课中我会学到什么?
选择 SOURCE、CLASS 或 RUNTIME 保留策略,并使用 @Target 限制目标元素 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Java Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「保留策略与目标类型」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Java Academy 课中编写并运行代码吗?
能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 定义注解:元素与默认值
- 保留策略与目标类型
- 运行时注解处理
- 编译时注解处理器