天天看點

Annotation注解及元注解

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

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

常見的幾個注解

1、@TargetApi

2、@RequiresApi

3、@suppressLint

4、@SuppressWarnings

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

Lint會按照API版本M以上掃描代碼,而不是project中指定的minSDKVersion,可以使得高版本Api在低版本SDK上Lint不報錯。如果隻加這個注解,表明這段代碼隻能在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可以找到預先定義好的所有Error、Warning。對于多個錯誤,使用逗号隔開。

在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(以前總是看到這樣的注釋,但并不知道也是注解)

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

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的作用目标,具體TYPE、FIELD等代表什麼,可以在java.lang.annotation.ElementType裡面找到。

例如:TYPE表示

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

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

例如:@Override注解

@Target(ElementType.METHOD)  重寫,隻能作用于方法

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

public @interface Override {}

@Retention定義保留政策

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

2、PetentionPolicy.CLASS預設政策,會保留到編譯出位元組碼階段,運作時失效

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

@Documented   注解将被寫入javadoc中

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

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

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

繼續閱讀