JDK除了在java.lang下提供5个基本的注解之外,还在java.lang.annotation包下提供6个Meta注解(元注解),其中5个元注解都用于修饰其他的注解定义。先介绍常用的4个元注解。
一、使用@Retention
@Retention只能修饰注解定义,用于指定被修饰的注解可以保留多长时间,@Retention包含一个RetentionPolicy类型的value变量,使用@Retention必须为该value成员变量赋值。
value成员变量的取值只能是下面三个:
(1)RetentionPolicy.CLASS:编译器把注解记录在class文件中。当运行Java程序时,JVM不可获取注解信息,这是默认值。
(2)RetentionPolicy.RUNTIME:编译器把注解记录在class文件中。当运行Java程序时,JVM也可获取注解信息,程序可以通过反射获取该注解信息。
(3)RetentionPolicy.SOURCE:注解保留在源代码中,编译器直接丢弃这种注解。
如果需要通过反射来获取注解信息,就需要使用value属性值为RetentionPolicy.RUNTIME的@Retention。使用@Retention元注解可采用如下带啊吗为value指定值:
//定义@Testable注解保留到运行时
@Retention注解保留到运行时
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Testable{}
也可采用如下代码来为value指定值
//定义下面的@Testable注解将被编译器直接丢弃
@Retention(RetentionPolicy.SOURCE)
public @interface Testable{}
二、使用@Target
@Target也只能修饰注解定义,它用于指定被修饰的注解能修饰哪些程序单元。@Target元注解也包含一个value的成员变量,该成员变量的值只能是如下几个:
(1)ElementType.ANNOTATION_TYPE:指定该策略的注解只能修饰注解。
(2)ElementType.CONSTRUCTOR:指定该策略的注解只能修饰构造器。
(3)ElementType.FIELD:指定该策略的注解只能修饰成员变量。
(4)ElementType.LOCAL_VARIABLE:指定该策略的注解只能修饰局部变量。
(5)ElementType.METHOD:指定该策略的注解只能修饰方法定义。
(6)ElementType.PACKAGE:指定该策略的注解只能修饰包定义。
(7)ElementType.PARAMETER:指定该策略的注解只能修饰参数。
(8)ElementType.TYPE:指定该策略的注解可以修饰类、接口(包括注解类型)或枚举定义。
如下指定@ActionListeterFor注解只能修饰成员变量
@Target(ElementType.FIELD)
public @interface ActionListeterFor{}
指定@Testable注解只能修饰方法
@Target(ElementType.METHOD)
public @interface Testable
三、使用@Documented
@Documented用于指定该元注解修饰的注解类将被javadoc工具提取成文档,如果定义注解类时使用了@Documented修饰,则所有使用该注解修饰的程序元素的API文档将会包含该注解定义。
下面程序定义了一个Testable注解,程序使用@Documented来修饰@Testable注解,所以该注解将被javadoc工具所提取。
Testable.java
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
//定义Testable注解将被javadoc工具提取
@Documented
public @interface Testable
{
}
下面定义了一个MyTest类,该类的info()方法使用了@Testable修饰
MyTest.java
public class MyTest
{
//使用@Testable修饰info方法
/*
*简单测试方法
*/
@Testable
public void info()
{
System.out.println("info方法...");
}
}
四、使用@Inherited
@Inherited元注解指定被它修饰的注解将具有继承性——如果某个类使用了@Xxx注解(定义该注解时使用了@Inherited修饰),则其子类将自动被@Xxx修饰。
下面使用了@Inherited元注解修饰@Inheritable定义,则该注解将具有继承性。
import java.lang.annotation.*;
@Target(ElementType.TYPE)//指定被修饰的注解能修饰类、接口或枚举定义
@Retention(RetentionPolicy.RUNTIME)//当程序运行时,JVM可获取注解信息
@Inherited
public @interface Inheritable
{
}
下面定义了一个Base基类,该基类使用了@Inheritable修饰,则Base类的子类将会默认使用@Inheritable修饰
//@Inherited修饰的基类
@Inheritable
class Base
{
}
//IngeritableTest类继承了Base基类
//并未直接使用IngeritableTest注解修饰
public class IngeritableTest extends Base