天天看點

Android中@IntDef,@StringDef + 注解使用-替代Enum

使用枚舉的地方

在我們日常開發中經常要定義一些限定範圍内的常量,比如說,性别類型、大中小等,不能保證入參的範圍,如果要是提供Api給别人使用,更易出現傳參錯誤的情況:

public static final int TYPE_BIG = 1;
    public static final int TYPE_MIDDLE = 2;
    public static final int TYPE_LITTLE = 3;
    
    public int currentType = 0;
    /**
     * @param type 類型隻能為 1、2、3
     */
    public void setType(int type) {
        this.currentType = type;
    }
    public void main(String[] args){
        setType(88);
    }
           

這個setType方法設計目的是擷取類型,隻接受類型為1或2或3,但是調用時,隻要是int類型的都可以傳入,這顯然不是很好。在java中我們使用Enum枚舉來解決:

public static final int TYPE_BIG = 1;
    public static final int TYPE_MIDDLE = 2;
    public static final int TYPE_LITTLE = 3;

    public Type currentType;

    public enum Type {
        TYPE_BIG, TYPE_MIDDLE, TYPE_LITTLE
    }
    /**
     * @param type 類型隻能為 1、2、3
     */
    public void setType(Type type) {
        this.currentType = type;
        System.out.println(type);
    }
    public void main(String[] args){
        setType(Type.TYPE_BIG); 
        setType(88); // 這裡會編譯不通過,報紅
    }
           

使用枚舉的優點:

  • 利用枚舉,在setType()方法裡面對入參做了枚舉Type的限制
  • 對于想輸入任何非枚舉類Type裡面定義的枚舉常量,編譯都是不能通過的
  • 很好的解決了入參不明确、容易混亂的問題

當然枚舉也有缺點:

  • 每一個枚舉值都是一個對象,Enum枚舉值會比我們之前使用的常量類型占用更多的記憶體
  • 在Android中我們可以使用Enum,但是它又吃記憶體,要特别注意使用

在Android中可以使用**@IntDef+自定義注解**來替代Enum的作用

Android的support Annotation注解庫中,有@IntDef、@StringDef可以替代Enum使用

build.gradle檔案中添加依賴

implementation 'com.android.support:support-annotations:27.1.1'
           
public static final int TYPE_BIG = 1;
    public static final int TYPE_MIDDLE = 2;
    public static final int TYPE_LITTLE = 3;
    
    public int currentType;
    
    @IntDef({TYPE_BIG,TYPE_MIDDLE,TYPE_LITTLE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Type{}
    
    public void setType(@Type int type) {
        this.currentType = type;
        System.out.println(type);
    }
    public void main(String[] args){
        this.setType(TYPE_BIG); // 編譯通過
        this.setType(1); // 編譯不通過,報紅
        this.setType(10); // 編譯不通過,報紅
    }
           

如果我們在調用setType方法時傳入不在限制範圍内的數值 且 不是@IntDef修飾過得,都編譯不通過,這很好的解決傳值容易錯,又規避了Enum的缺點;同理,@StringDef是一樣的