Annotation註解及元註解

在使用許多第三方框架的時候,查閱源碼如ButterKnife等。發現許多註解的使用,頓時覺得註解都玩不溜怎麼稱霸武林。當然無論Java還是AndroidSDK中都有大量註解的使用,以前總是走馬觀花,印象中知道註解代表的意思,但開口總是說不清道不明,唯有總結方得始終。

註解是附加在代碼中的一些信息,可以幫助一些代碼分析工具如Lint分析代碼,輔助開發者改善代碼,對於開發者來說有個提示、警告的作用。但註解不會改變代碼邏輯。在此總結了幾個Android開發常見的註解的解釋,以及對元註解的基本認識。


常見的幾個註解

1@TargetApi

2@RequiresApi

3@suppressLint

4@SuppressWarnings


@TargetApi(Build.VERSION_CODES.M)@TargetApi(23)

Lint會按照API版本M以上掃描代碼,而不是project中指定的minSDKVersion,可以使得高版本Api在低版本SDKLint不報錯。如果只加這個註解,表明這段代碼只能在23及以上的系統上運行,如果你非要在23以下的系統上運行,那該警告的已經警告了,你只是忽略了警告,但運行時該錯還是錯。


@RequiresApi(api = Build.VERSION_CODES.M)

表示註解目標只能夠在指定的版本API及以上運行,消除高版本Api在低版本SDK上的報錯,作用上和TargetApi相同,只是在詞面上更清楚表達了這是一個建議,而不僅僅是爲了消除高版本Api在低版本SDK上的報錯。從官方的表述可以看出更推薦使用RequiresApi替換TargetApi


@SuppressLint("NewApi")

最直接暴力屏蔽指定名稱的報錯,這裏的NewApi對應的具體錯誤名稱是:Calling new methods on older versions。這裏的NewApi只是一個縮寫名稱。相比於@TargetApi指定了版本號,SuppressLint是一律屏蔽,所以一般不建議使用。當然還可以指定任何其他Lint定義好的錯誤名稱。在settings中查找Inspections可以找到預先定義好的所有ErrorWarning。對於多個錯誤,使用逗號隔開。

XML中類似的做法有:

tools:ignore="ScrollViewCount,UselessParent"忽略XML中的兩個警告。


@SuppressWarnings("NumericOverflow")

屏蔽NumericOverflow警告,如:int a = 1 / 0;

一般的語句註解方式suppress for statement 

    @SuppressWarnings("NumericOverflow")

     int a = 10 / 0;

註釋註解方式statement for statement with comment

     //noinspection NumericOverflow(以前總是看到這樣的註釋,但並不知道也是註解)

     int a = 10 / 0;

當然,這些註解可以使用在許多地方如:classmethodstatement,分別對應由大到小不同的作用域類、方法、語句,當然作用域範圍越大,那麼性能損耗自然越大。


Annotation不影響代碼邏輯

這些註解的作用只是去除Lint的錯誤警告,並不能影響任何的代碼邏輯。

所以必須在代碼中添加相應的兼容性判斷代碼,如:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

      color = getColor(R.color.colorAccent);

}

當然,當你添加完上述兼容代碼後,警告也就消失了。


元註解(註解的註解)

常見的元註解:

1@Documented

2@Inherited

3@Retention

4@Target

分析SuppressLint的定義:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

@Retention(RetentionPolicy.CLASS)

public @interface SuppressLint {

 value();

}

@Target定義作用目標

其中@Target指定了SuppressLint的作用目標,具體TYPEFIELD等代表什麼,可以在java.lang.annotation.ElementType裏面找到。

例如:TYPE表示

/** Class, interface (including annotation type), or enum declaration */

即包含了類、接口(包括註解)、枚舉類型。

例如:@Override註解

@Target(ElementType.METHOD)  重寫,只能作用於方法

@Retention(RetentionPolicy.SOURCE)  只存在於編碼階段,編譯階段就失效了

public @interface Override {}


@Retention定義保留策略

1PetentionPolicy.SOURCE 僅保留在源碼階段,編譯階段就失效

2PetentionPolicy.CLASS默認策略,會保留到編譯出字節碼階段,運行時失效

3PetentionPolicy.RUNTIME 保留到VM的運行時階段,可通過反射獲得


@Documented   註解將被寫入javadoc

@Inherited   子類可以繼承父類中的該註解

@Repeatable   找不到例子,有待理解

@Native   尚處於Preview狀態,表示常量有可能被本地代碼引用


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章