jdk1.5起开始提供了4个元注解:@Target、@Retention、@Documented、@Inherited。何谓元注解?就是注解的注解。
在程序开发中,有时候我们需要自定义一个注解,这个自定义注解类就需要被元注解修饰,以定义该类的一些基本特征。
例如,我们创建一个LogAnnotation的自定义注解类:
@Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @
interface LogAnnotation { String module() default ""; }
@interface意思是声明一个注解,方法名对应参数名,返回值类型对应参数类型。
<>@Target
@Target注解用于定义注解的使用位置,如果没有该项,表示注解可以用于任何地方。@Target的格式为:
// 单参数 @Target({ ElementType.METHOD }) // 多参数 @Target(value = {ElementType.
METHOD,ElementType.TYPE})
@Target的ElementType取值有以下类型:
* TYPE:类,接口或者枚举
* FIELD:域,包含枚举常量
* METHOD:方法
* PARAMETER:参数
* CONSTRUCTOR:构造方法
* LOCAL_VARIABLE:局部变量
* ANNOTATION_TYPE:注解类型
* PACKAGE:包
<>@Retention
@Retention注解用于指明修饰的注解的生存周期,即会保留到哪个阶段。格式为:
@Retention(RetentionPolicy.RUNTIME)
RetentionPolicy的取值包含以下三种:
* SOURCE:源码级别保留,编译后即丢弃。
* CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
* RUNTIME:运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。
<>@Documented
指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值。
<>@Inherited
@Inherited注解用于标注一个父类的注解是否可以被子类继承,如果一个注解需要被其子类所继承,则在声明时直接使用@Inherited注解即可。如果没有写此注解,则无法被子类继承。下面做一个测试:
//自定义一个注解 @interface MyAnnoation { public String key() default "key1"; public
Stringvalue() default "value1"; } @Target(ElementType.TYPE) @Retention(
RetentionPolicy.RUNTIME) @Documented //如果父类使用了HeritedApplication注解,则子类应该继承
@Inherited @MyAnnoation @interface HeritedApplication { }
//父类使用了@HeritedApplication注解 @HeritedApplication class Person { } class Student
extends Person{ } class AnnotationInherited{ public static void main(String[]
args) throws Exception { Class clazz = Student.class;
//Student类是否有@HeritedApplication if(clazz.isAnnotationPresent(HeritedApplication
.class)){ System.out.println("true"); } } }
运行程序,结果为 true。