Java注解初探

Java注解定義

注解(Annotation),也叫元數(shù)據(jù)。一種代碼級(jí)別的說(shuō)明。它是JDK1.5及以后版本引入的一個(gè)特性,與類(lèi)、接口、枚舉是在同一個(gè)層次。它可以聲明在包、類(lèi)、字段、方法、局部變量、方法參數(shù)等的前面,用來(lái)對(duì)這些元素進(jìn)行說(shuō)明,注釋。

Java注解作用

1、編寫(xiě)文檔:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)生成文檔【生成文檔doc文檔】
2、代碼分析:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)對(duì)代碼進(jìn)行分析【使用反射】
3、編譯檢查:通過(guò)代碼里標(biāo)識(shí)的元數(shù)據(jù)讓編譯器能夠?qū)崿F(xiàn)基本的編譯檢查【Override】

Java注解分類(lèi)

1、內(nèi)置的作用在代碼的注解

  • @Override - 檢查該方法是否是重寫(xiě)方法。如果發(fā)現(xiàn)其父類(lèi),或者是引用的接口中并沒(méi)有該方法時(shí),會(huì)報(bào)編譯錯(cuò)誤。
  • @Deprecated - 標(biāo)記過(guò)時(shí)方法。如果使用該方法,會(huì)報(bào)編譯錯(cuò)誤。
  • @SuppressWarnings - 指示編譯器去忽略注釋中聲明的警告。
    2、內(nèi)置的作用在其它注解上的注解(原注解)
  • @Retention - 標(biāo)示這個(gè)注解怎么保存,是只在代碼中,還是編入class文件中,或者是在運(yùn)行時(shí)可以通過(guò)反射訪問(wèn)。
  • @Documented - 標(biāo)記這些注釋是否包含在用戶(hù)文檔中。
  • @Target - 表示這個(gè)注釋的作用范圍
  • @Inherited - 標(biāo)示注釋可被繼承類(lèi)獲取
    3、從Java7開(kāi)始,額外添加了3個(gè)注釋?zhuān)?/li>
  • @SafeVarargs - Java7開(kāi)始支持,忽略任何使用參數(shù)為范型變量的方法或構(gòu)造函數(shù)調(diào)用產(chǎn)生的警告。
  • @Functionallnterface - Java8開(kāi)始支持,標(biāo)識(shí)一個(gè)匿名函數(shù)或函數(shù)式接口。
  • @Repeatable - Java8開(kāi)始支持,標(biāo)識(shí)某注解可以在同一個(gè)聲明上使用多次

Annotation組成部分

java Annotation的組成中,有3個(gè)非常重要的主干類(lèi)。它們分別是:

  • Annotation.java
public interface Annotation {
    /**
     * @return true if the specified object represents an annotation
     */
    boolean equals(Object obj);

    /**
     * @return the hash code of this annotation
     */
    int hashCode();

    /**
     * @return a string representation of this annotation
     */
    String toString();

    /**
     * @return the annotation type of this annotation
     */
    Class<? extends Annotation> annotationType();
}
  • ElementType.java
public enum ElementType {
    /** 類(lèi)、接口(包括注釋類(lèi)型)或枚舉聲明*/
    TYPE,

    /** 字段聲明(包括枚舉常量)*/
    FIELD,

    /** 方法聲明 */
    METHOD,

    /** 正式的參數(shù)聲明 */
    PARAMETER,

    /** 構(gòu)造函數(shù)聲明 */
    CONSTRUCTOR,

    /** 本地變量聲明*/
    LOCAL_VARIABLE,

    /** 注釋類(lèi)型聲明 */
    ANNOTATION_TYPE,

    /** 包聲明 */
    PACKAGE,

    /**
     * 類(lèi)型參數(shù)聲明
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * 字體的使用
     * @since 1.8
     */
    TYPE_USE
}
  • RetentionPolicy.java
public enum RetentionPolicy {
    /*注釋將被編譯器丟棄*/
    SOURCE,

    /**
     * 注釋由編譯器記錄在類(lèi)文件中
     * 但不需要在運(yùn)行時(shí)被VM保留。這是默認(rèn)設(shè)置
     */
    CLASS,

    /**
     * 注釋由編譯器和記錄在類(lèi)文件中
     * 在運(yùn)行時(shí)被VM保留,因此它們可以被反射式讀取。
     */
    RUNTIME
}

自定義注釋

//元注釋
public @interface 注釋名稱(chēng){
    // 屬性列表
}

1、創(chuàng)建一個(gè)注釋

@Deprecated //是否為過(guò)期方法
@Documented //標(biāo)記這些注釋是否包含在用戶(hù)文檔中
@Retention(RetentionPolicy.RUNTIME)//注釋怎么保存
@Target(ElementType.METHOD)//注釋用在哪里
@Inherited //注釋是否可以被繼承
public @interface TestAnnotation {
    String value();
}

2、創(chuàng)建一個(gè)使用注釋的類(lèi)

public class HelloAnnotationClient {
    @TestAnnotation("matthew")
    public void sayHello() {
        System.out.println("Inside sayHello method...");
    }
}

3、通過(guò)反射獲取方法及注釋攜帶的信息注意,如果要攜帶信息能在運(yùn)行時(shí)被反射獲取需要設(shè)置@Retention(RetentionPolicy.RUNTIME)

public class HelloAnnotationTest {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        HelloAnnotationClient helloAnnotationClient = new HelloAnnotationClient();
        Method method = helloAnnotationClient.getClass().getMethod("sayHello");
        if (method.isAnnotationPresent(TestAnnotation.class)) {
            TestAnnotation annotation = method.getAnnotation(TestAnnotation.class);
            System.out.println("Value:"+annotation.value());
            method.invoke(helloAnnotationClient);
        }
    }

}

4、運(yùn)行的結(jié)果

Value:matthew
Inside sayHello method...

Process finished with exit code 0
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容