Android中使用注解替代枚舉

枚舉最大的作用是提供了類型安全。為了彌補(bǔ)Android平臺不建議使用枚舉的缺陷,官方推出了兩個(gè)注解,IntDef和StringDef,用來提供編譯期的類型檢查。
首先,引入依賴包:

implementation 'com.android.support:support-annotations:27.1.0'

定義一個(gè)注解

public @interface TaskStatus {

}

是的,類似于接口的定義,加個(gè) @ 符號。

注解一般使用步驟

那么對于上面的枚舉和常量都不 work 的場景,如何使用枚舉解決呢?

  1. 定義注解類,添加常量
@Retention(RetentionPolicy.SOURCE)
public @interface TaskStatus {
    int UN_KNOW = -1;
    int UN_START = 0;
    int PROGRESSING = 1;
    int COMPLETED = 2;
}

和接口成員一樣,注解類的成員默認(rèn)就是 public static final 修飾的。

@Retention(RetentionPolicy.SOURCE) 表示告訴編譯器,該注解是源代碼級別的,生成 class 文件的時(shí)候這個(gè)注解就被編譯器自動去掉了。

doSth() 方法:

public class TaskHelper {

    public static void doSth(@TaskStatus int status){
        switch (status){
            case TaskStatus.UN_KNOW:
                //do something
                break;
            case TaskStatus.UN_START:
                break;
            case TaskStatus.PROGRESSING:
                break;
            case TaskStatus.COMPLETED:
                break;
        }
    }
}

可以看出,doSth() 方法的參數(shù)是 int 類型的,但是使用 @TaskStatus 進(jìn)行了注解,這樣外界就無法傳遞 TaskStatus之外的成員作為參數(shù)了。

  1. 調(diào)用
TaskHelper.doSth(TaskStatus.UN_START);

在調(diào)用時(shí),IDE 會提示 @TaskStatus int status,提醒我們傳入 TaskStatus 類型的值。

同時(shí),調(diào)用者如果再隨便傳入一個(gè) int 值,雖然可以運(yùn)行,但代碼會爆紅,lint 檢查將會給與警告:

Must be one of: TaskStatus.UN_KNOW, TaskStatus.UN_START, TaskStatus.PROGRESSING, TaskStatus.COMPLETED

如此,保證了類型安全。但也只是警告,仍然可以運(yùn)行,但總比沒有警告強(qiáng)多了。

補(bǔ)充

其實(shí)這種用法在 Android 源碼中屢見不鮮,比如 Resources 下的 getDrawable() 方法:

public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
        final Drawable d = getDrawable(id, null);
        //...
        return d;
    }

使用時(shí),我們一般會這么用:

getResources().getDrawable(R.drawable.ic_launcher);

雖然是 int 值,但是當(dāng)我們這么用時(shí):

getResources().getDrawable(111);

就會爆紅并提示:

Expected resource of type drawable

再補(bǔ)充一點(diǎn),為了防止在我們定義的常量值重復(fù),我們還可以使用Android 注解支持庫(support-annotations)中的 @IntDef 來限定常量不允許重復(fù):

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

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