JavaSE第七十讲:Retention及RetentionPolicy详解

来源:互联网 发布:js除以100 编辑:程序博客网 时间:2024/05/16 07:50

1. 继续上一讲内容,上一讲的内容讲到自定义注解

package com.ahuier.annotation;public @interface AnnotationTest {//注意不要忘记小括号//这边给他定义注解信息为默认值,则在AnnotationTest中注解时候,@AnnotationTest()参数默认为hello,如果有设值就按设定的值注解String value() default "hello";EnumTest value2(); //枚举也可以做为注解的值}enum EnumTest{Hello, World, Welcome;}
package com.ahuier.annotation;/* * @AnnotationTest(value = "hello") 与 @AnnotationTest("hello")都可以,前提是定义的注解里面必须是 value 值 */@AnnotationTest(value2 = EnumTest.Welcome) public class AnnotationUsage {@AnnotationTest(value = "hello", value2 = EnumTest.World)public void method(){System.out.println("usage of annotation");}public static void main(String[] args) {AnnotationUsage usage = new AnnotationUsage();usage.method();}}

【说明】:Single-value annotiong: value成员设定默认值,用"default"关键词。当然注解也可以用数组形式来设置值。

2. 学习完以上两个程序之后,这两个程序是基于上一讲自定义注解内容所讲的,现在我们要做一些实际的注解的例子。

自定义Annotation类型,使用@interface自行定义Annotation型态时候,实际上是自动继承了java.lang.annotation.Annotation接口,由编译程序自动为您完成其它产生的细节,在定义Annotation型态,不能继承其它的Annotation态或是接口

查看JDK Doc文档的Annotation接口

java.lang.annotation
Interface Annotation
public interface Annotation
    The common interface extended by all annotation types. Note that an interface that manually extends this one does not define an annotation type. Also note that this interface does not itself define an annotation type.

[它是一个被annotation类型所继承的公共的接口.注意一个接口手动的去继承这个接口并不是定义了注解类型。再注意这个接口本身并没有定义注解类型]

当我们使用 @interface 关键字定义一个注解时,该注解隐含地继承了 java.lang.annotation.Annotation 接口;如果我们定义了一个接口,并且让该接口继承自 Annotation,那么我们所定义的接口依然还是接口而不是注解;Annotation 本身是接口类型而不是注解类型。可以与 Enum 类比。

3. 定义Annotation型态时也可以使用包来管理类别,方法类同于类的导入功能


4. 告知编译程序如何处理@Retention  [Retention: 保持,保留]

1) java.lang.annotation.Retention型态可以在您定义Annotation型态时,指示编译程序该如何对待您的自定义的Annotation型态

缺省情况下编译程序会将Annotation信息留在.class档案中,但不被虚拟机读取,而仅用于编译程序或工具程序运行时提供信息。

2) 我们在注解中应该采取什么样的一种保持策略呢?如果下图说明所示,我们需要提供RetentionPolicy枚举型态。


查看JDK文档中的RetentionPolicy

java.lang.annotation 
Enum RetentionPolicy
Annotation retention policy. The constants of this enumerated type describe the various policies for retaining annotations. They are used in conjunction with the Retention meta-annotation type to specify how long annotations are to be retained. 

[Retention是一个注解,里面有一个枚举RetentionPolicy,这个枚举决定了Retention这个注解应该如何去保持,默认情况下,这个注解信息会被保持到class文件当中。]

有三个枚举常量如下图所示:


默认情况下是第一种Class枚举常量。


5. 现在利用注解给我们提供的Retention和RetentionPloicy讲一个例子


这边我们查看JDK Doc文档 Override注解、Deprecated注解、SuppressWarnings注解,查看他们分别是对应的注解时机是以上三种的哪一种。

比如Override注解:表示在编译的时候被丢弃,也就是仅仅是定义在源文件中的。类似查看其他两个。

@Target(value=METHOD)

@Retention(value=SOURCE)

public @interface Override


如果注解能在运行的时候保留下来,我们就可以通过反射的机制将其信息读取出来,下面就是用反射的API的来提取注解信息


查看JDK Doc文档中的AnnotatedElement可以发现反射中的Class、Constructor、Field、Method、Package等类别,都实现了AnnotatedElement接口。上图的这几个方法都是很重要的。

package com.ahuier.annotation;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;/* * 使用Retention修饰这个注解, * 告诉这个注解在使用的时候仅仅用在源文件中,还是可以用到.Class文件中,还是即可以用到.Class文件,又能在运行过程中通过反射的方式读取出来 */@Retention(RetentionPolicy.CLASS)public @interface MyAnnotation {String hello() default "ahuier";String world();}
package com.ahuier.annotation;@MyAnnotation(hello = "beijing", world = "shanghai")public class MyTest {@MyAnnotation(hello = "tianjin", world = "shangdi")@Deprecated@SuppressWarnings("unchecked")       //一个方法可以有多个注解所修饰public void output(){System.out.println("output something!");}}





原创粉丝点击