Java中Annotation(注释)系列学习笔记(3)

来源:互联网 发布:淘宝改打折影响权重吗 编辑:程序博客网 时间:2024/05/17 01:52

【转】Java中Annotation(注释)系列学习笔记(3)

三.JDK的元Annotation
  JDK除了java.lang下提供了3个基本Annotation之外,还在java.lang.annotation包下提供了四个Meta Annotation(元Annotation),这四个都是用于修饰其它Annotation定义

(1)使用@Retention
  @Retention只能用于修饰一个Annotation定义,用于该Annotation可以保留多长时间,@Retention包含一个RetentionPolicy类型的value成员变量,所以使用@Retention时必须为该value成员变量指定值.
value成员变量的值只能是如下三个

RetentionPolicy.CLASS:编译器将把注释记录在class文件中。当运行Java程序时,JVM不再保留注释。这是默认值。
RentionPolicy.RUNTIME:编译器将把注释记录在class文件中。当运行java程序时,JVM也会保留注释,程序也可以通过反射获取该注释。
RentionPolicy.SOURCE:编译器直接丢弃这种策略的注释。

  在前面的程序中,因为我们要通过反射获取注释信息,所以我们指定value属性值为RetentionPolicy.RUNTIME. 使用@Retention元数据Annotation可采用如下代码为value指定值.


//定义下面的Testable Annotation的保留到过行时
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Testable{}

 

也可以采用如下代码来为value指定值
@Retention(RetentionPolicy.SOURCE)
public @interface Testable{}

  上面代码使用@Retention元数据Annotation时,并未直接通过value=RetentionPolicy.SOURCE的方式来为成员变量指定值,这是因为如果Annotation的成员变量名为value时,程序中可以直接在Annotation后的括号里指定该成员变量的值,无须用name=value的形式.

说明
  如果我们定义的Annotation类型里只有一个value成员变量,使用该Annotation时可以直接在Annotation后的括号里指定value成员变量的值,无须使用name=value的形式。

 

(2)使用@Target
  @Target也是用于修饰一个Annotation定义,它用于指定被修饰的Annotation能用于修饰哪些程序元素。@Target Annotation也包含一个名为value的成员变量。该成员变量的值只能是如下几个

ElementType.ANNOTATION_TYPE: 指定该策略的Annotation只能修饰Annotation
ElementType.CONSTRUCTOR:指定该策略的Annotation能修饰构造器
ElementType.FIELD:指定该策略的Annotation只能修饰成员变量
ElementType.LOCAL_VARIABLE:指定该策略的Annotation只能修饰局部变量
ElementType.METHOD 指定该策略的Annotation只能修饰方法定义
ElementType.PACKAGE 指定该策略的Annotaion只能修饰包定义
ElementType.PARAMETER 指定该策略的Annotation可以修饰参数
ElementType.TYPE 指定该策略的Annotaion可以修饰类,接口(包括注释类型)或枚举定义

  与使用@Retention类似的是,使用@Target也可以直接在括号里指定value值,可以无须使用name=value的形式。如

下代码指定@ActionListenerFor Annotation只能修饰成员变量
@Target(ElementType.FIELD)
public @interface ActionListenerFor{}

 

如下代码指定@Testable Annotation只能修饰方法
@Target(ElementType.METHOD)
public @interface Testable{}

 

(3)使用@Documented
  @Documented用于指定该元Annotation修饰的Annotation类将被javadoc工具提取成文档,如果定义Annotatin类时使用了@Documented修饰,则所有使用该Annotation修饰的程序元素API文档中将会包含该Annotation说明

  下面程序定义了一个Testable Annotation程序使用@Documented来修饰@Testable Annotation定义,所以该Annotation将被 javadoc工具提取
@Retention(RetentionPolicy.RUNTIME)   
@Target(ElementType.METHOD)
//定义Testable Annotation将被javadoc工具提取
@Documented
public @interface Testable
{
}


  上面程序中的@Documented代码决定了所有使用@Testable Annotation的地方都会被javadoc工具提取到api文档中

  下面程序中定义了一个 MyTest类,该类中的infor方法使用Testable Annotation修饰
程序清单
public class MyTest
{
 //使用@Testable修饰info方法
 @Testable
 public void info()
 {
  System.out.println("info方法...");
 }
}


使用javadoc工具为Testable.java ,MyTest文件生成api文档后如下面所示



如果,我们去掉不用@Documented修饰Testable的话,则不会被javadoc提取


(4)使用@Inherited
  @Inherited元Annotation指定被它修饰的Annotation将具有继承性。如果某个类使用了Annotaion(使用Annotation时使用了@Inherited修饰)修饰,则其子类将自动具有A注释。

 

下面使用@Inherited元数据注释定义了一个Inherited Annotation,该Annotation将具有继承性

程序清单
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
// @Inherited
public @interface Inheritable
{
}

  上面程序中表明了@Inheritable Annotation具有继承性,如果某个类使用了该Annotation 修饰,则该类的子类将自动具有@Inheritable Annotation

  下面程序定义了一个Base基类,该基类使用了@Inherited修饰,则Base类的子类将自动具有@Inherited Annotation

程序清单
//使用@Inheritable修饰的Base类
@Inheritable
class Base
{
}
//TestInheritable类只是继承了Base类,
//并未直接使用@Inheritable Annotiation修饰
public class TestInheritable extends Base
{
 public static void main(String[] args)
 {
  //打印TestInheritable类是否具有Inheritable Annotation
  System.out.println(TestInheritable.class.isAnnotationPresent(Inheritable.class));
 }
}

 

运行效果图如下




总结
  1.
上面程序中的Base类使用了@Inheritable Annotation修饰,而该Annotaion具有可继承性,所以其子类也将具有@Inheritable Annotation,运行上面程序看到输出 true
  2.如果将上面的Inheritable.java程序中的@Inherited注释或者删除,将会导致Inheritable Annotation不具有继承性,运行上面程序将会输出 false

转自:http://blog.sina.com.cn/heyitang

0 0
原创粉丝点击