021android初級(jí)篇之a(chǎn)ndroid的Context

021android初級(jí)篇之Android注解支持(Support Annotations)

定義:注解(Annotation),也叫元數(shù)據(jù)。

一種代碼級(jí)別的說明。它是JDK1.5及以后版本引入的一個(gè)特性,與類、接口、枚舉是在同一個(gè)層次。它可以聲明在包、類、字段、方法、局部變量、方法參數(shù)等的前面,用來對(duì)這些元素進(jìn)行說明,注釋。

作用分類:

  1. 編寫文檔:通過代碼里標(biāo)識(shí)的元數(shù)據(jù)生成文檔【生成文檔doc文檔】
  2. 代碼分析:通過代碼里標(biāo)識(shí)的元數(shù)據(jù)對(duì)代碼進(jìn)行分析【使用反射】
  3. 編譯檢查:通過代碼里標(biāo)識(shí)的元數(shù)據(jù)讓編譯器能夠?qū)崿F(xiàn)基本的編譯檢查【Override】

常見的注解

@IntDef/StringDef: 類型定義注解

整型除了可以作為資源的引用之外,也可以用作“枚舉”類型使用。

@IntDef和”typedef”作用非常類似,你可以創(chuàng)建另外一個(gè)注解,然后用@IntDef指定一個(gè)你期望的整型常量值列表,最后你就可以用這個(gè)定義好的注解修飾你的API了。

appcompat庫里的一個(gè)例子:

import android.support.annotation.IntDef;
...
public abstract class ActionBar {
...
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
@Retention(RetentionPolicy.SOURCE)
public @interface NavigationMode {}

public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;

@NavigationMode
public abstract int getNavigationMode();

public abstract void setNavigationMode(@NavigationMode int mode);

上面非注解的部分是現(xiàn)有的API。我們創(chuàng)建了一個(gè)新的注解(NavigationMode)并且用@IntDef標(biāo)注它,通過@IntDef我們?yōu)榉祷刂祷蛘邊?shù)指定了可用的常量值。我們還添加了@Retention(RetentionPolicy.SOURCE)告訴編譯器這個(gè)新定義的注解不需要被記錄在生成的.class文件中(譯者注:源代碼級(jí)別的,生成class文件的時(shí)候這個(gè)注解就被編譯器自動(dòng)去掉了)。

使用這個(gè)注解后,如果你傳遞的參數(shù)或者返回值不在指定的常量值中的話,IDE將會(huì)標(biāo)記出這種情況。
button.setLayoutDirection(View.Text_ALIGNMENT_TEXT_START);
Must be one of View.LAYOUT_DIRECTION_RTL,VI...

你也可以指定一個(gè)整型是一個(gè)標(biāo)記性質(zhì)的類型;這樣客戶端代碼就通過|,&等操作符同時(shí)傳遞多個(gè)常量了:

@IntDef(flag=true, value={
        DISPLAY_USE_LOGO,
        DISPLAY_SHOW_HOME,
        DISPLAY_HOME_AS_UP,
        DISPLAY_SHOW_TITLE,
        DISPLAY_SHOW_CUSTOM
})
@Retention(RetentionPolicy.SOURCE)
public @interface DisplayOptions {}

最后,還有一個(gè)字符串版本的注解,就是@StringDef,它和@IntDef的作用基本上是一樣,所不同的是它是針對(duì)字符串的。該注解一般不常用,但是有的時(shí)候非常有用,比如在限定向Activity#getSystemService方法傳遞的參數(shù)范圍的時(shí)候。

要了解關(guān)于類型注解的更多詳細(xì)信息,請參考

Nullness Annotations

@Nullable注解能被用來標(biāo)注給定的參數(shù)或者返回值可以為null。
類似的,@NonNull注解能被用來標(biāo)注給定的參數(shù)或者返回值不能為null。

如果一個(gè)本地變量的值為null(比如因?yàn)檫^早的代碼檢查它是否為null),而你又把它作為參數(shù)傳遞給了一個(gè)方法,并且該方法的參數(shù)又被@NonNull標(biāo)注,那么IDE會(huì)提醒你,你有一個(gè)潛在的崩潰問題。

v4 support library中的FragmentActivity的示例代碼:

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
...

/**
 * Add support for inflating the <fragment> tag.
 */
@Nullable
@Override
public View onCreateView(String name, @NonNull Context context, @NonNull AttributeSet attrs) {
...

(如果你執(zhí)行Analyze > Infer Nullity,或者你在鍵入時(shí)把@NonNull替換成了@NotNull,那么IDE可能會(huì)提供附加的IntelliJ注解。參考底部的“IntelliJ Annotations”段落了解更多)

注意@NonNull和@Nullable并不是對(duì)立的:還有第三種可能:未指定。當(dāng)你沒有指定@NonNull或者@Nullable的時(shí)候,工具就不能確定,所以這個(gè)API也就不起作用。

最初,我們在findViewById方法上標(biāo)注@Nullable,從技術(shù)上說,這是正確的:findViewById可以返回null。但是如果你知道你在做什么的時(shí)候(如果你傳遞給他一個(gè)存在的id)他是不會(huì)返回null的。當(dāng)我們使用@Nullable注解它的時(shí)候,就意味著源代碼編輯器中會(huì)有大量的代碼出現(xiàn)高亮警告。如果你已經(jīng)意識(shí)到每次使用該方法都應(yīng)該明確的進(jìn)行null檢查,那么就只能用@Nullable標(biāo)注返回值。有個(gè)經(jīng)驗(yàn)規(guī)則:看現(xiàn)有的“好的代碼”(比如審查產(chǎn)品代碼),看看這些API是怎么被使用的。如果該代碼為null檢查結(jié)果,你應(yīng)該為方法注解@Nullable。

參考鏈接

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

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

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