Java中,@Retention
是一个注解,用于指定注解的保留策略,即注解在何时有效。RetentionPolicy
是@Retention
注解的一个枚举类型,定义了三个值:
SOURCE(源代码级别)
该注解只保留在源代码中,编译时会被丢弃,不会包含在编译后的类文件中。
通过这种保留策略,注解仅在编写代码时起作用,对运行时没有任何影响。
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation {
//...
}
CLASS(类文件级别)
该注解会被保留在编译后的类文件中,但在运行时不可见。
这是默认的保留策略,如果不显式指定,编译器会使用CLASS。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.CLASS)
public @interface ClassRetentionAnnotation {
String value() default "CLASS 保留策略的默认值";
}
在这个例子中,我们定义了一个自定义注解 ClassRetentionAnnotation
,并将保留策略设置为 CLASS
。这意味着该注解将包含在编译后的类文件(*.class
)中,但在运行时将不可用。
public class MyClass {
@ClassRetentionAnnotation
public void myMethod() {
// 方法实现
}
}
在上面的代码中,@ClassRetentionAnnotation
应用于 myMethod
方法。虽然注解信息会出现在编译后的 MyClass.class
文件中,但在运行时将无法访问。
RUNTIME(运行时级别)
该注解将被保留在编译后的类文件中,并在运行时可以通过反射机制访问。
这种保留策略用于在运行时处理注解,例如通过反射获取注解信息并做相应的处理。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimeRetentionAnnotation {
String value() default "RUNTIME 保留策略的默认值";
}
在这个例子中,自定义注解 RuntimeRetentionAnnotation
的保留策略为 RUNTIME
,这意味着它将在编译后的类文件中保留,并且在运行时可访问。
import java.lang.reflect.Method;
public class MyRuntimeClass {
@RuntimeRetentionAnnotation
public void myRuntimeMethod() {
// 方法实现
}
public static void main(String[] args) {
Method[] methods = MyRuntimeClass.class.getDeclaredMethods();
for (Method method : methods) {
RuntimeRetentionAnnotation annotation = method.getAnnotation(RuntimeRetentionAnnotation.class);
if (annotation != null) {
System.out.println("在方法 " + method.getName() + " 上找到 RuntimeRetentionAnnotation 注解");
System.out.println("注解值: " + annotation.value());
}
}
}
}
包含关系
如果一个注解的保留策略是 SOURCE
,那么它只存在于源代码中,编译时会被丢弃,不会包含在生成的类文件中。因此,CLASS
保留策略包含了 SOURCE
。
如果一个注解的保留策略是 CLASS
,那么它会包含在生成的类文件中,但在运行时不可见。而 RUNTIME
保留策略包含了 CLASS
,因为它在编译后的类文件中保留,并且可以在运行时通过反射访问。
所以,它们的包含关系可以总结为:SOURCE < CLASS < RUNTIME。SOURCE
是最短暂的,只在源代码级别存在;CLASS
在编译后的类文件中存在;而 RUNTIME
在运行时也可以通过反射访问。
评论区