0Pricing
Java Academy · 课时

保留策略与目标类型

选择 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 output

CLASS 保留:字节码分析

CLASS 注解会包含在 .class 文件中,供字节码分析工具(PMD、FindBugs、ASM)使用,但不能在运行时通过反射读取。

@Retention(RetentionPolicy.CLASS)
public @interface ThreadSafe {}
// Visible in bytecode, invisible to Class.getAnnotation() at runtime

RUNTIME 保留:反射处理

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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 定义注解:元素与默认值
  2. 保留策略与目标类型
  3. 运行时注解处理
  4. 编译时注解处理器
← 返回 Java Academy