一 簡介
注解是Java 1.5引入的,可以提供代碼的額外信息,目前正在被廣泛應用。除了Java內置注解,我們也可以自定義注解。以下就是一個自定義注解的例子:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Msg {
String DEFAULT_MSG = "msg";
String msg() default DEFAULT_MSG
}
自定義注解分析:
1.@interface關鍵字定義注解,
2.注解可以被其它注解修飾(如果我說注解,這也太繞了),最重要的就是元注解。
3.注解和接口類似,內部可以定義常量和方法。
4.注解定義的方法有一些限制:方法不能有參數;返回值只能是基本類型、字符串、Class、枚舉、注解、及以上類型的數組;可以包含默認值。
二 元注解
元注解就是定義注解的注解,包含@Target、@Retention、@Inherited、@Documented這四種。
2.1 @Target
描述注解的使用目標,取值有:
ElementType.PACKAGE 注解作用于包
ElementType.TYPE 注解作用于類型(類,接口,注解,枚舉)
ElementType.ANNOTATION_TYPE 注解作用于注解
ElementType.CONSTRUCTOR 注解作用于構造方法
ElementType.METHOD 注解作用于方法
ElementType.PARAMETER 注解作用于方法參數
ElementType.FIELD 注解作用于屬性
ElementType.LOCAL_VARIABLE 注解作用于局部變量
默認可以作用于以上任何目標。
@Target注解源碼如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Target {
ElementType[] value();
}
注解方法返回值是ElementType[],ElementType枚舉類型,枚舉值就是@Target注解的可取值。方法名value,這樣在使用注解時,可以不需要指定方法名。
2.2 @Retention
描述注解的生命周期,取值有:
RetentionPolicy.SOURCE 源碼中保留,編譯期可以處理
RetentionPolicy.CLASS Class文件中保留,Class加載時可以處理
RetentionPolicy.RUNTIME 運行時保留,運行中可以處理
默認RetentionPolicy.CLASS 值
@Retention注解源碼如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Retention {
RetentionPolicy value();
}
注解方法返回值是枚舉類型RetentionPolicy,枚舉值就是@Retention注解的可取值。
2.3 @Inherited
標記注解,使用@Inherited修飾的注解作用于一個類,則該注解將被用于該類的子類。
@Inherited注解源碼如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Inherited {
}
2.4 @Documented
描述注解可以文檔化,是一個標記注解。
在生成javadoc的時候,是不包含注釋的,但是如果注解被@Documented修飾,則生成的文檔就包含該注解。
@Documented注解源碼如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Documented {
}
三 自定義注解實例
3.1 自定義注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Msg {
String DEFAULT_MSG = "msg";
String msg() default DEFAULT_MSG;
}
3.2 使用自定義注解
@Msg(msg = "Test")
public class Test {
}
3.3 獲取注解
public class Main {
public static void main(String[] args) {
Test test = new Test();
Class tClass = test.getClass();
Msg msg = (Msg) tClass.getAnnotation(Msg.class);
System.out.println(msg.msg());
}
}
運行結果:Test
因為Msg注解的生命周期為RetentionPolicy.RUNTIME,所以可以運行時通過反射獲取。對于編譯器處理的注解,可以使用APT處理。