安卓進(jìn)階指南Annotation總結(jié)篇(一)

前言:為什么要寫這篇文章?主要是為了總結(jié)一下最近學(xué)習(xí)內(nèi)容,記錄方便以后查閱。以前有一次面試有人問到看過 ButterKnife 實(shí)現(xiàn)的原理是什么?答:注解,反射。然而真的是這樣嗎?。也在網(wǎng)絡(luò)上看到很多關(guān)于這方面的資料,稂莠不齊,所以趁這階段有時間特地把 Annotation 搞搞清楚。文中會出現(xiàn)引用一些文章的部分,文末已注明出處,表示感謝。

CkID59daIh.png

代碼地址:android-annotation-tutorial

一、為什么需要了解注解

  • 為了看懂如 Retrofit,Arouter, dagger2,ButterKnife 等開源庫,不得不先看懂注解
  • Java虛擬機(jī)可以完成這些標(biāo)示對應(yīng)的功能,通過注解我們可以完全代替配置文件的編寫
  • 注解將一些本來重復(fù)性的工作,變成程序自動完成,簡化和自動化該過程
  • 為了更好地提升開發(fā)效率和代碼質(zhì)量

二、什么是注解

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 源代碼的語法元數(shù)據(jù)。類、方法、變量、參數(shù)、包都可以被注解,可用來將信息元數(shù)據(jù)與程序元素進(jìn)行關(guān)聯(lián)。Annotation 中文常譯為“注解”。

三、分類

按照來源劃分

類型 說明
來自JDK的注解 java.lang.annotation.* 等
來自Android API的注解 android.annotation.* ,如TargetApi、SuppressLint等
來自第三方的注解 如 support-annotations
自定義注解 N/A

JDK 內(nèi)置的幾個常用注解:

  • @Override——當(dāng)我們想要復(fù)寫父類中的方法時,我們需要使用該注解去告知編譯器我們想要復(fù)寫這個方法。這樣一來當(dāng)父類中的方法移除或者發(fā)生更改時編譯器將提示錯誤信息。

  • @Deprecated——當(dāng)我們希望編譯器知道某一方法不建議使用時,我們應(yīng)該使用這個注解。Java在javadoc 中推薦使用該注解,我們應(yīng)該提供為什么該方法不推薦使用以及替代的方法。此注解是對不應(yīng)該,或者將要淘汰的方法進(jìn)行標(biāo)識,當(dāng)編程人員使用時就會給予提示。這個功能在一些基礎(chǔ)jar包,規(guī)范,框架等的中我們經(jīng)??梢钥吹?,還保留這些方法是為了兼容前邊的一些版本,有一過度的階段??聪逻叺倪@種效果應(yīng)該都見過:

  • @SuppressWarnings——這個僅僅是告訴編譯器忽略特定的警告信息,例如在泛型中使用原生數(shù)據(jù)類型。它的保留策略是SOURCE(譯者注:在源文件中有效)并且被編譯器丟棄。此注解表示去除一些警告,但是里邊需要我們制定參數(shù)

  • @Documented—— 指明擁有這個注解的元素可以被javadoc此類的工具文檔化。這種類型應(yīng)該用于注解那些影響客戶使用帶注釋的元素聲明的類型。如果一種聲明使用Documented進(jìn)行注解,這種類型的注解被作為被標(biāo)注的程序成員的公共API。

  • @Target——指明該類型的注解可以注解的程序元素的范圍。該元注解的取值可以為TYPE,METHOD,CONSTRUCTOR,FIELD等。如果Target元注解沒有出現(xiàn),那么定義的注解可以應(yīng)用于程序的任何元素。

  • @Inherited——指明該注解類型被自動繼承。如果用戶在當(dāng)前類中查詢這個元注解類型并且當(dāng)前類的聲明中不包含這個元注解類型,那么也將自動查詢當(dāng)前類的父類是否存在Inherited元注解,這個動作將被重復(fù)執(zhí)行知道這個標(biāo)注類型被找到,或者是查詢到頂層的父類。允許子類繼承父類中的注解

  • @Retention——指明了該Annotation被保留的時間長短。RetentionPolicy取值為SOURCE,CLASS,RUNTIME。

來自 JDK 的注解著重關(guān)注一下元注解,也就是第三種分類標(biāo)準(zhǔn);

在安卓源碼中有很多如下代碼段,

static {
        if (VERSION.SDK_INT < VERSION_CODES.KITKAT) {
            ROOT_REATTACHED_LISTENER = null;
        } else {
            ROOT_REATTACHED_LISTENER = new OnAttachStateChangeListener() {
                @TargetApi(VERSION_CODES.KITKAT)
                @Override
                public void onViewAttachedToWindow(View v) {
                    // execute the pending bindings.
                    final ViewDataBinding binding = getBinding(v);
                    binding.mRebindRunnable.run();
                    v.removeOnAttachStateChangeListener(this);
                }

                @Override
                public void onViewDetachedFromWindow(View v) {
                }
            };
        }
    }

@TargetApi(VERSION_CODES.KITKAT)
如果只加這個注解,表明這段代碼只能在19及以上的系統(tǒng)上運(yùn)行,如果你非要在19以下的系統(tǒng)上運(yùn)行,那該警告的已經(jīng)警告了,你只是忽略了警告,但運(yùn)行時該錯還是錯;

關(guān)于 Android 注解具體介紹請看下一篇文章

按照運(yùn)行機(jī)制劃分

類型 說明
源碼注解 RetentionPolicy.SOURCE 標(biāo)記,用于告訴編譯器一些信息
編譯時注解 RetentionPolicy.CLASS 編譯時動態(tài)處理,如動態(tài)生成代碼
運(yùn)行時注解 RetentionPolicy.RUNTIME 運(yùn)行時動態(tài)處理,如得到注解信息

元注解

元注解的作用就是負(fù)責(zé)注解其他注解。java 1.5定義了4個meta-annotation類型,
在1.8中又添加了兩個,用來提供對Annotation 類型做說明。該注解位于包

java.lang.annotation 下:

元注解 詳情
@Target since 1.5 用于描述注解的使用范圍
@Retention since 1.5 定義了該Annotation被保留的時間長短
@Document since 1.5 用于描述其它類型的annotation應(yīng)該被作為被標(biāo)注的程序成員的公共API
@Inherited since 1.5 闡述了某個被標(biāo)注的類型是被繼承的
@Repeatable since 1.8 N/A
@Native since 1.8 N/A

四、最后

優(yōu)點(diǎn)
  1. 集中管理對象和對象之間的組合關(guān)系,易于閱讀
  2. 編譯期間容易發(fā)現(xiàn)錯誤的出處
缺點(diǎn)
  1. 運(yùn)行中的錯誤很難定位,調(diào)試難度較大
  2. 管理分散,基本每個類上都有
何時選擇

如果客戶需求進(jìn)行發(fā)生變化,那么采用配置文件的方式會好一些 , 有利于擴(kuò)展。
如果客戶需求不會頻繁發(fā)生變化, 那么使用注解非常好,開發(fā)效率快.

最后提醒下:

要用好注解,必須熟悉java 的反射機(jī)制,注解的解析完全依賴于反射 , 不要濫用注解。平常我們編程過程很少接觸和使用注解,只有做設(shè)計,且不想讓設(shè)計有過多的配置時。

這篇文章中我們并不設(shè)計怎么使用注解,主要是能對它有個總體印象 , 后面三篇文章會按照運(yùn)行機(jī)制來進(jìn)行舉例。

參考鏈接:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容