Java筆記:註解

來源:互聯網
上載者:User

標籤:col   ted   基礎   except   ide   語義   地方   reflect   try   

一、基礎知識

Java支援在源檔案中嵌入補充資訊,這類資訊稱為註解(中繼資料)。註解不會改變程式的行為,因此也不會改變程式的語義。

 

二、聲明

上述聲明表示註解。註解都只能包含方法聲明,不能為這些方法提供實現,而是由Java實現。所有的註解類型都自動擴充了Annotation介面,其指定了annotationType方法,該方法返回調用註解的對象。

在聲明了註解之後就可以用來註解聲明了。所有的聲明都可以有與之關聯的註解,甚至註解本身也可以被註解。使用註解時,需要為註解的成員提供值。

class Solution {    @interface MyAnnotation {        String str();        int val() default 0;//使用預設值    }    @MyAnnotation(str = "printHello", val = 1)    public static void print() {        System.out.println("Hello");    }}
View Code


三、指定保留原則

註解保留原則決定了在什麼位置丟棄註解。Java於java.lang.annotation.RetentionPolicy枚舉中定義了三種保留策咯:

  • SOURCE策略僅在源檔案中保留註解而編譯期拋棄。
  • CLASS策略在編譯時間將註解儲存至class檔案中但是Java虛擬機器不能得到這些註解。
  • RUNTIME策略提供了永久的註解。
import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)@interface MyAnnotation {    String str();    int val();}
View Code

 

四、使用反射擷取註解

如果為註解指定RUNTIME保留原則,任何程式在啟動並執行時候都可以使用反射來查詢註解。反射時能夠在運行時擷取類相關資訊的特性。

import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.reflect.Method;@Retention(RetentionPolicy.RUNTIME)@interface MyAnnotation {    String str();    int val();}class Solution {    @MyAnnotation(str = "Annotation content", val = 0)    public static void printAnnotation() {        Solution ob = new Solution();        try {            Class<?> c = ob.getClass();            Method method = c.getMethod("printAnnotation");            MyAnnotation anno = method.getAnnotation(MyAnnotation.class);            System.out.println(anno);        } catch (NoSuchMethodException exc) {            System.out.println("Method does not exist");        }    }    public static void main(String[] args) {        printAnnotation();    }}
View Code

擷取所有註解。

import java.lang.annotation.Annotation;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.reflect.Method;@Retention(RetentionPolicy.RUNTIME)@interface MyAnnotationA {    String str();}@Retention(RetentionPolicy.RUNTIME)@interface MyAnnotationB {    int val();}@MyAnnotationA(str = "Class annotation content")@MyAnnotationB(val = 1)class Solution {    @MyAnnotationA(str = "Method annotation content")    @MyAnnotationB(val = 0)    public static void printAnnotation() {        Solution ob = new Solution();        try {            Annotation[] annos = ob.getClass().getAnnotations();            for (Annotation a : annos)                System.out.println(a);            Method method = ob.getClass().getMethod("printAnnotation");            annos = method.getAnnotations();            for (Annotation a : annos)                System.out.println(a);        } catch (NoSuchMethodException exc) {            System.out.println("Method does not exist");        }    }    public static void main(String[] args) {        printAnnotation();    }}
View Code


五、相關介面

getAnnotation方法和getAnnotations方法均由AnnotatedElement介面定義,該介面支援註解反射。AnnotatedElement介面此外還定義了如下方法:

  • getDeclaredAnnotations方法返回調用對象中存在的所有非繼承註解。
  • isAnnotationPresent方法返回註解與對象是否關聯。

 

六、標記註解

標記註解是特殊類型的註解,其中不包含成員。標記註解的唯一目的就是標記聲明,確定標記註解是否存在的最好方式是使用isAnnotationPresent方法。

import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.reflect.Method;@Retention(RetentionPolicy.RUNTIME)@interface Marker {}class Solution {    @Marker    public static void printAnnotation() {        Solution ob = new Solution();        try {            Class<?> c = ob.getClass();            Method method = c.getMethod("printAnnotation");            System.out.println(method.isAnnotationPresent(Marker.class));        } catch (NoSuchMethodException exc) {            System.out.println("Method does not exist");        }    }    public static void main(String[] args) {        printAnnotation();    }}
View Code


七、單成員註解

單成員註解通常只包含一個成員,允許使用縮寫形式指定成員值。該成員名稱必須是value,若包含其他成員則必須有預設值。

import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)@interface Single {    String value();    int i() default 0;}class Solution {    @Single("printHello")    public static void print() {        System.out.println("Hello");    }}
View Code

 

八、內建註解

  • Retention指定保留原則,只能註解其他註解。
  • Documented是標記介面,通知其他工具註解將被文檔化,只能註解其他註解。
  • Target指定可以應用註解的宣告類型,只能註解其他註解。可同時指定多個值。
  • Inherited是標記註解,指明超類註解可被子類繼承,只能註解其他註解。
  • Override是標記註解,指明必須重寫超類中的方法,只能註解方法。
  • Deprecated是標記註解,指明聲明是過時的,已被新的形式取代。
  • FunctionalInterface指明介面是函數式介面。函數式介面僅包含一個由lambda運算式所使用的抽象方法。
  • SafeVarargs是標記註解,指明沒有發生與可變長度參數相關的不安全動作,只能用於方法和建構函式。
  • SuppressWarnings指明抑制編譯器可能會報告的警告,使用字串表示警告名稱。

 

九、類型註解

最早的註解只能應用於聲明,但是現在已經能應用於使用類型的大多數地方。擴充後的這種註解稱為類型註解。類型註解允許工具對代碼執行額外檢查,從而協助避免錯誤。

import java.lang.annotation.ElementType;import java.lang.annotation.Target;@Target(ElementType.CONSTRUCTOR)@interface ConstructorAnno {}@Target(ElementType.TYPE_USE)@interface TypeAnno {}@Target(ElementType.TYPE_PARAMETER)@interface ParameterAnno {}@Target(ElementType.FIELD)@interface FieldAnno {}class Solution<@ParameterAnno T> {    @FieldAnno    @TypeAnno    private T data;    @ConstructorAnno    Solution(@TypeAnno T data) {        this.data = data;    }}
View Code

 

Java筆記:註解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.