Java筆記:註解
阿新 • • 發佈:2018-02-18
ram 獲取 val 永久 技術分享 function rri 名稱 class a
一、基礎知識
Java支持在源文件中嵌入補充信息,這類信息稱為註解(元數據)。註解不會改變程序的行為,因此也不會改變程序的語義。
二、聲明
上述聲明表示註解。註解都只能包含方法聲明,不能為這些方法提供實現,而是由Java實現。所有的註解類型都自動擴展了Annotation接口,其指定了annotationType方法,該方法返回調用註解的對象。
在聲明了註解之後就可以用來註解聲明了。所有的聲明都可以有與之關聯的註解,甚至註解本身也可以被註解。使用註解時,需要為註解的成員提供值。
class Solution { @interface MyAnnotation { String str();View Codeint val() default 0;//使用默認值 } @MyAnnotation(str = "printHello", val = 1) public static void print() { System.out.println("Hello"); } }
三、指定保留策略
註解保留策略決定了在什麽位置丟棄註解。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保留策略,任何程序在運行的時候都可以使用反射來查詢註解。反射時能夠在運行時獲取類相關信息的特性。
importView Codejava.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(); } }
獲取所有註解。
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筆記:註解