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 String value() 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。