java.lang.annotation.Retention可以在您定义Annotation型态时,指示编译器如何对待您的自定义 Annotation,预设上编译器会将Annotation资讯留在class档案中,但不被虚拟机器读取,而仅用于编译器或工具程式运行时提供资讯。
在使用Retention型态时,需要提供java.lang.annotation.RetentionPolicy的列举型态:
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE, //编译器处理完Annotation资讯后就没事了
CLASS, //编译器将Annotation储存于class档中,预设
RUNTIME //编译器将Annotation储存于class档中,可由VM读入
}
RetentionPolicy为SOURCE的例子是SuppressWarnings,这个资讯的作用仅在告知编译器抑制警讯,所以不必将这个资讯储存于class档案。
RetentionPolicy为RUNTIME的时机,可像是您使用Java设计一个程式码分析工具,您要VM读出Annotation资讯,以在分析程式中使用,搭配Reflection机制,就可以达到这个目的。
在J2SE 5.0中新增了java.lang.reflect.AnnotatedElement这个介面,当中定义有四个方法:
public Annotation getAnnotation(Class annotationType);
public Annotation[] getAnnotations();
public Annotation[] getDeclaredAnnotations();
public boolean isAnnotationPresent(Class annotationType);
Class、Constructor、Field、Method、Package等类别,都实作了AnnotatedElement这个介面,所以您可以从这些类别的实例上,分别取得标示于其上的Annotation与其资讯,如果RetentionPolicy为RUNTIME的话。
举个例子来说,假设您设计了以下的Debug Annotation:
* Debug.java
package onlyfun.caterpillar;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Debug {
String value();
String name();
}
由于RetentionPolicy为RUNTIME,编译器在处理Debug Annotation时,会将之编译至class档中,并可以VM读出Annotation资讯,接着我们将Debug用于程式中:
* SomeObject.java
package onlyfun.caterpillar;
public class SomeObject {
@Debug(
value = "unit",
name = "debug1"
)
public void doSomething() {
// ....
}
}
可以设计一个工具程式来读取Annotation资讯:
* DebugTool.java
package onlyfun.caterpillar;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class DebugTool {
public static void main(String[] args)
throws NoSuchMethodException {
Class<SomeObject> c = SomeObject.class;
Method method = c.getMethod("doSomething");
if(method.isAnnotationPresent(Debug.class)) {
System.out.println("@Debug is found.");
Debug debug = method.getAnnotation(Debug.class);
System.out.println("\tvalue = " + debug.value());
System.out.println("\tname = " + ());
}
else {
System.out.println("@Debug is not found.");
}
Annotation[] annotations = method.getAnnotations();
for(Annotation annotation : annotations) {
System.out.println(
annotation.annotationType().getName());
}
}
}
程式的执行结果如下:
@Debug is found.
value = unit
name = debug1
onlyfun.caterpillar.Debug
分享到:
相关推荐
在Java中,注解有三种关键特性:Retention、Documented和Inherited,它们分别控制注解的生命周期、文档化和继承性。 1. **Retention(保留)** Retention注解用于定义一个注解的生存周期,即在程序的哪个阶段仍然...
@Retention(RetentionPolicy.RUNTIME ) SOURCE 给编译器看的# 源码存在,字节码不存在 CLASS 给虚拟机的类加载器看的,#源码,.class存在, RUNTIME 用于反射 #源码,.class 字节码 存在 @Documented 这个注解可以...
Java 元注解包括四大类:@Retention、@Target、@Documented、@Inherited 等。 1.@Retention @Retention 用于指定注解的保留期限,可以设置为 SOURCE、CLASS 或 RUNTIME。 * RetentionPolicy.SOURCE:注解只保留在...
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在 class 字节码文件中存在,但运行时无法获得 @Retention(RetentionPolicy.RUNTIME) // 注解会在 class 字节码文件中存在,在运行时可以通过反射获取...
在Java中,有五种内置的元注解,它们分别是`@Target`、`@Retention`、`@Documented`、`@Inherited`以及`@Repeatable`。这里我们主要讨论前四种,因为`@Repeatable`是在Java 8中引入的,用于表示一个注解可以重复应用...
@Retention注解则用于指定注解的存储策略,共有三个策略:SOURCE、CLASS、RUNTIME,其中SOURCE级别注解仅保留在源码中,CLASS级别注解在编译时被编译器保留,而RUNTIME级别注解则被JVM保留,能够在运行时被反射机制...
@Retention meta-annotation 定义了 Annotation 被保留的时间长短。它用于描述注解的生命周期,即:被描述的注解在什么范围内有效。@Retention 取值包括: * SOURCE:在源文件中有效(即源文件保留) * CLASS:在 ...
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface MyAutowired { // 可以添加一些额外的属性,如required等 } ``` 接着,我们可以创建一个实现了`BeanPostProcessor`接口的类,...
`@Target`定义了注解可以应用于哪些程序元素(如类、方法、字段等),`@Retention`指定了注解的生命周期,如是否在运行时可见。例如,`RetentionPolicy.RUNTIME`表示注解将在运行时可用,以便在程序运行时进行检查或...
1. **编译时处理(Compile-Time Processing)**:通过`@Retention(RetentionPolicy.SOURCE)`或`@Retention(RetentionPolicy.CLASS)`指定注解只在源码或字节码阶段有效,常用于代码生成、格式检查等。Java编译器在...
`@Retention(RetentionPolicy.CLASS)`表示注解仅存在于类文件中,`@Retention(RetentionPolicy.RUNTIME)`则允许在运行时通过反射访问,而`@Retention(RetentionPolicy.SOURCE)`意味着注解只存在于源代码,编译后会被...
1. **编译时处理**:通过`@Retention(RetentionPolicy.CLASS)`或`@Retention(RetentionPolicy.SOURCE)`,注解可以在编译时被处理。编译器可以检查注解并采取相应行动,例如,检查`@Override`是否真的重写了父类方法...
- **元注解**:用于定义注解的注解,如`@Retention`、`@Target`、`@Documented`、`@Inherited`。 2. **注解的保留策略** - `@Retention(RetentionPolicy.SOURCE)`:注解只存在于源码阶段,编译后不保留。 - `@...
`@Target(ElementType.TYPE)` 表示这个注解可以应用于类级别,`@Retention(RetentionPolicy.RUNTIME)` 指定这个注解在运行时仍然有效,以便于反射机制能够读取。 2. `@MyAutowired` 是一个字段注解,用于标记那些...
* 保留在一个 class 文件中(`@Retention(RetentionPolicy.CLASS)`) * 保留在程序运行期间(`@Retention(RetentionPolicy.RUNTIME)`) 定义注解 一个简单的注解: ```java public @interface Annotation01 { //...
- **@Retention**:用来指定注解的生命周期,如前面提到的`@Retention(RetentionPolicy.RUNTIME)`。 - **@Documented**:用来指定是否将注解信息包含在API文档中。 - **@Inherited**:用来指定注解是否可以被子类...
- `@Retention`:决定注解的生命周期,何时以及如何保留注解信息。有SOURCE、CLASS和RUNTIME三个策略。 - `@Documented`:指示是否将注解包含在JavaDoc文档中。 - `@Inherited`:使子类继承父类的注解,但只有`@...
`@Retention` 元注解则指定该注解将在运行时保留,因此可以通过反射访问。注解类中定义的成员(如 `primaryKey`、`allowNull` 和 `unique`)被称为注解元素,它们可以设置默认值。 注解元素的类型有限,包括基本...
在这个示例中,我们定义了一个名为`TestMethod`的Annotation,并使用`@Retention`指定了其生命周期为`RUNTIME`,即在运行时仍然有效。同时使用`@Target`指定了该Annotation可以应用于方法(`ElementType.METHOD`)。...