在使用許多第三方框架的時候,查閱源碼如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(以前總是看到這樣的註釋,但並不知道也是註解)
int a = 10 / 0;
當然,這些註解可以使用在許多地方如: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狀態,表示常量有可能被本地代碼引用