天天看点

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是一样的