您好,登錄后才能下訂單哦!
前言
對于注解,相信大家都不陌生了,但是這種熟悉對于Android開發者來說,也就是僅僅是它認識你,你不認識它吧,因為,我們幾乎都停留在用上了。像dagger2,像retrofit,像greenDao,他們都是滿滿的使用了注解,而我們只是停留在知其然缺不知其所以然的層面,那么我本次分享講分成幾批博客共享給大家一個體系的又不失針對Android平臺需要的恰到好處的給大家整理真正需要掌握的知識體系。
注解的定義
Java 注解用于為 Java 代碼提供元數據。作為元數據,注解不直接影響你的代碼執行,但也有一些類型的注解實際上可以用于這一目的。Java 注解是從 Java5 開始添加到 Java 的。
注解即標簽
如果把代碼想象成一個具有生命的個體,注解就是給這些代碼的某些個體打標簽
如何自定義注解
注解通過 @interface關鍵字進行定義。
public?@interface?Test?{ }
它的形式跟接口很類似,不過前面多了一個 @ 符號。上面的代碼就創建了一個名字為 Test 的注解。
你可以簡單理解為創建了一張名字為 Test的標簽。
使用注解
@Testpublic?class?TestAnnotation?{ }
創建一個類 TestAnnotation,然后在類定義的地方加上 @Test就可以用 Test注解這個類了
你可以簡單理解為將 Test 這張標簽貼到 TestAnnotation這個類上面。
元注解是可以注解到注解上的注解,或者說元注解是一種基本注解,但是它能夠應用到其它的注解上面。
如果難于理解的話,你可以這樣理解。元注解也是一張標簽,但是它是一張特殊的標簽,它的作用和目的就是給其他普通的標簽進行解釋說明的。
元標簽有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 種。
@Retention
Retention 的英文意為保留期的意思。當 @Retention 應用到一個注解上的時候,它解釋說明了這個注解的的存活時間。
它的取值如下:
RetentionPolicy.SOURCE 注解只在源碼階段保留,在編譯器進行編譯時它將被丟棄忽視。
RetentionPolicy.CLASS 注解只被保留到編譯進行的時候,它并不會被加載到 JVM 中。
RetentionPolicy.RUNTIME 注解可以保留到程序運行的時候,它會被加載進入到 JVM 中,所以在程序運行時可以獲取到它們
@Target
Target 是目標的意思,@Target 指定了注解運用的地方
你可以這樣理解,當一個注解被 @Target 注解時,這個注解就被限定了運用的場景。
類比到標簽,原本標簽是你想張貼到哪個地方就到哪個地方,但是因為 @Target 的存在,它張貼的地方就非常具體了,比如只能張貼到方法上、類上、方法參數上等等。@Target 有下面的取值
ElementType.ANNOTATION_TYPE 可以給一個注解進行注解
ElementType.CONSTRUCTOR 可以給構造方法進行注解
ElementType.FIELD 可以給屬性進行注解
ElementType.LOCAL_VARIABLE 可以給局部變量進行注解
ElementType.METHOD 可以給方法進行注解
ElementType.PACKAGE 可以給一個包進行注解
ElementType.PARAMETER 可以給一個方法內的參數進行注解
@Documented
顧名思義,這個元注解肯定是和文檔有關。它的作用是能夠將注解中的元素包含到 Javadoc 中去。ElementType.TYPE 可以給一個類型進行注解,比如類、接口、枚舉
@Inherited
Inherited 是繼承的意思,但是它并不是說注解本身可以繼承,而是說如果一個超類被 @Inherited 注解過的注解進行注解的話,那么如果它的子類沒有被任何注解應用的話,那么這個子類就繼承了超類的注解。
@Repeatable
Repeatable 自然是可重復的意思。@Repeatable 是 Java 1.8 才加進來的,所以算是一個新的特性。
什么樣的注解會多次應用呢?通常是注解的值可以同時取多個。
注解的屬性
注解的屬性也叫做成員變量。注解只有成員變量,沒有方法。
需要注意的是,在注解中定義屬性時它的類型必須是 8 種基本數據類型外加 類、接口、注解及它們的數組
注解中屬性可以有默認值,默認值需要用 default 關鍵值指定
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public?@interface?Test{int?id()?default?-1;String?msg()?default?"Hello"; }
上面代碼定義了 TestAnnotation 這個注解中擁有 id 和 msg 兩個屬性。在使用的時候,我們應該給它們進行賦值。
賦值的方式是在注解的括號內以 value="" 形式,多個屬性之前用 ,隔開
@Test(id=1,msg="hello?annotation")public?class?TestAnnotation?{ }
注解的提取
注解與反射。
注解通過反射獲取。首先可以通過 Class 對象的 isAnnotationPresent() 方法判斷它是否應用了某個注解
public?boolean?isAnnotationPresent(Class<??extends?Annotation>?annotationClass)?{}
然后通過 getAnnotation() 方法來獲取 Annotation 對象。
public?<A?extends?Annotation>?A?getAnnotation(Class<A>?annotationClass)?{
或者是 getAnnotations() 方法。
public?Annotation[]?getAnnotations()?{}
前一種方法返回指定類型的注解,后一種方法返回注解到這個元素上的所有注解。
如果獲取到的 Annotation 如果不為 null,則就可以調用它們的屬性方法了。比如
@Test()public?class?TestDemo{public?static?void?main(String[]?args)?{????boolean?hasAnnotation?=??????????????????TestDemo.class.isAnnotationPresent(Test.class);????????if?(?hasAnnotation?)?{ ????????????TestAnnotation?testAnnotation?=?????TestDemo.class.getAnnotation(Test.class); ????????????System.out.println("id:"+testAnnotation.id()); ????????????System.out.println("msg:"+testAnnotation.msg()); ????????} ????} }
注解的使用場景
提供信息給編譯器: 編譯器可以利用注解來探測錯誤和警告信息
編譯階段時的處理: 軟件工具可以用來利用注解信息來生成代碼、Html文檔或者做其它相應處理。
運行時的處理: 某些注解可以在程序運行的時候接受代碼的提取
值得注意的是,注解不是代碼本身的一部分。
架構技術詳解和學習路線與資料分享請看這篇;《BATJ一線大廠最主流的Android高級架構技術;體系詳解+學習路線》
(包括自定義控件、NDK、架構設計、混合式開發工程師(React native,Weex)、性能優化、完整商業項目開發等)
阿里P8級Android架構師技術腦圖;
全套體系化高級架構視頻;七大主流技術模塊,視頻+源碼+筆記
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。