Java注解(Annotation)详解
轉:
Java注解(Annotation)詳解
幻海流心 2018.05.23 15:20 字數 1775 閱讀 380評論 0喜歡 1Java注解(Annotation)詳解
1.Annotation的概念
An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may be annotated. Annotations have no direct effect on the operation of the code they annotate.
- 注解是一種可以添加到Java源代碼的元數據.
- 類,方法,變量,參數,包都可以被注解.
- 注解對注解的代碼并沒有直接的影響.
- 注解僅僅是個標記.注解之所以起作用是對其解析后做了相應的處理
2.Annotation分類
- 標準Annotation
- 標準Annotation是指Java內置的三個Annnotaion:
- @Override:用于修飾此方法覆蓋了父類的方法.
- @Deprecated:用于修飾已經過時的方法.
- @SuppressWarnnings:用于通知java編譯器禁止特定的編譯警告.
- 元Annotation(注解的注解)
- 元Annotation是用來定義Annotation的Annotation
- 元Annotation可以定義Annotation的作用范圍,使用在什么元素上等
- 元注解共有四種@Retention, @Target, @Inherited, @Documented
- 自定義Annotation
3.元Annotation
- @Retention:注在其他的注解A上,用來說明A的保留范圍,可選值 SOURCE(源碼時),CLASS(編譯時),RUNTIME(運行時),默認為 CLASS
- SOURCE:A只保留在源碼中,A會被編譯期忽略.(源碼可用)
- CLASS:A會通過編譯保存在CLASS文件中,但會被JVM在運行時忽略,運行時不可見.(源碼+CLASS可用)
- RUNTIME:A會被JVM獲取,并在運行時通過反射獲取.(源碼+CLASS+運行時均可用)
- @Target:注在其他的注解A上,用來限制A可用修飾那些程序元素.未標注Target表示無限制,可修飾所有元素.
- ANNOTATION_TYPE: A可以應用到其他注解上
- CONSTRUCTOR: A可以使用到構造器上
- FIELD: A可以使用到域或屬性上
- LOCAL_VARIABLE: A可以使用到局部變量上。
- METHOD: A可以使用到方法上。
- PACKAGE: A可以使用到包聲明上。
- PARAMETER: A可以使用到方法的參數上
- TYPE: A可以使用到類,接口(包括注解),或枚舉的聲明上
- @Inherited:默認情況下,父類的注解不會被子類繼承.
- Inherited注在其他的注解A上.
- 只有當A是注解在類Class上面,Inherited才會起作用,其他任何情況下無效果.
- 當A注解在類C上面,則C的所有子孫類,都會繼承應用A注解;
- @Documented:注在其他的注解A上,A將會作為Javadoc產生的文檔中的內容。注解都默認不會成為成為文檔中的內容。
4.自定義Annotation
創建自定義Annotation流程
- public @interface 自定義注解名稱 public @interface CustomAnnotation{***}
- 設置自定義Annotation的保留范圍和目標,Retention和Target是最重要的兩個元Anitation.
- 設置自定義Annotation的注解參數(注解成員)
- 注解參數支持的數據類型
- 所有基本數據類型(int,float,boolean,byte,double,char,long,short)
- String類型
- Class類型
- enum類型
- Annotation類型
- 以上所有類型的一維數組
- 注解參數聲明方式
- 自定義Annotation的參數類型必須滿足上一條1到6中的范圍.
- 自定義Annotation的參數訪問方法只能是public,或不寫.
- 自定義Annotation的參數可以加 default 設置默認值.
- 自定義Annotation若只有1個參數,使用value().
- 注解參數支持的數據類型
自定義Annotation的注解參數的默認值
注解元素必須有確定的值,要么在定義注解的默認值中指定,要么在使用注解時指定,非基本類型的注解元素的值不可為null。因此, 使用空字符串或0作為默認值是一種常用的做法。這個約束使得處理器很難表現一個元素的存在或缺失的狀態,因為每個注解的聲明中,所有元素都存在,并且都具有相應的值,為了繞開這個約束,我們只能定義一些特殊的值,例如空字符串或者負數,一次表示某個元素不存在,在定義注解時,這已經成為一個習慣用法。
示例:使用剛剛創建的自定義注解
5.Annotation解析
- 運行時 Annotation 解析
運行時 Annotation 指 @Retention 為 RUNTIME 的 Annotation
- Class,Method,Field中都有以下3個方法可以調用
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass) 按照傳入的參數獲取指定類型的注解。返回null說明當前元素不帶有此注解。
- public final boolean isAnnotationPresent(Class<? extends Annotation> annotationType) 檢查傳入的注解是否存在于當前元素。
- public Annotation[] getAnnotations() 返回該元素的所有注解,包括沒有顯式定義該元素上的注解。
- 運行時 Annotation 解析示例
public void testCustomAnnotation() { try { Class cls = Class.forName("com.jet.annotation.AnnotationTestClass"); CustomAnnotation customAnnotation = (CustomAnnotation)cls.getAnnotation(CustomAnnotation.class); System.out.println("customAnnotation mySkill:" + cus.mySkill()); System.out.println("customAnnotation attr1:" + cus.attr1()); System.out.println("customAnnotation attr2:" + cus.attr2()); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
- 編譯時 Annotation 解析
編譯時 Annotation 指 @Retention 為 CLASS 的 Annotation,甴編譯器自動解析
6.編譯時Annotation解析
編譯時Annotation解析 相對復雜,下面單獨進行分析
首先申明:下面內容僅僅討論 編譯時Annotation的解析
- 注解處理器是一個在javac中的,用來在編譯時掃描和處理注解的工具
- 我們可以為特定的注解,注冊自定義的注解處理器
- 在編譯期間,JVM會自動運行注冊過的注解處理器
- 一個注解的Annotation Processor,以Java代碼(或者編譯過的class)為輸入,生成.java文件作為輸出.這意味著我們可以生成新的Java代碼!這些生成的Java代碼是在生成的.java文件中,新生成的.java文件會和普通的手動編寫的Java源代碼一樣被javac編譯
關于編譯時Annotation解析,這里推薦一篇文章【Android】注解框架(三)-- 編譯時注解,手寫ButterKnife,按照文章上面流程敲一遍代碼,相信可以對自定義注解的創建及解析有一個深入的了解!
轉載于:https://www.cnblogs.com/libin6505/p/11227101.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Java注解(Annotation)详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core 模型验证的一个
- 下一篇: 最简单的http服务器实现