使用@IntDef @StringDef替代enum

xiaoxiao2021-02-28  31

为什么要使用枚举

举一个例子,例如我们要为一个bean赋值一个person的性别属性,因为性别只有男女,所以我们通常的做法是定义两个整型int,来区分“男女”性别

public class SexTest{ private final int MAN = 101, WOMEN = 102; private int sex; //设置性别 public void setSex(int sex){ this.sex = sex; } //获取性别 public String getSex(){ if(MAN == sex) return "男"; if(WOMEN == sex) return "女"; return "未知"; } public static void main(String[] args){ setSex(101); int sex = getSex(); System.out.println("sex: " + sex); //输出:sex: 男 //设置为102入参 setSex(102); String resultSex = getSex(); System.out.println("resultSex: " + resultSex); //输出:resultSex: 未知 } }

由上面的例子可以看出,当我们定义了一个男女的final整型作为入参时,不一定保证入参的都是我们想要的入参,这里就有一个“类型不安全”的问题出现。而枚举就可以解决这个问题

首先定义一个枚举类,里面有男,女两个枚举常量

public class SexTest{ public static enum Sex { MAN, WOMEN } private Sex sex; //设置性别 public void setSex(Sex sex){ this.sex = sex; } //获取性别 public String getSex(){ if(Sex.MAN == sex) return "男"; if(Sex.WOMEN == sex) return "女"; return "未知"; } public static void main(String[] args){ //这里的入参必须为Sex枚举类中的其中一个枚举常量 //绝对不允许输入没有再Sex枚举里面定义的常量 setSex(Sex.MAN); String resultSex = getSex(); System.out.println("resultSex: " + resultSex); //out:resultSex: 男 } }

所以我们可以看到,我们利用枚举,在setSex()方法里面对入参做了枚举Sex的限制,对于我们想输入任何非枚举类Sex里面定义的枚举常量,编译都是不能通过的。 这就很好的限制了入参混乱的问题。

使用 Enum 的缺点

每一个枚举值都是一个对象,在使用它时会增加额外的内存消耗,所以枚举相比与 Integer 和 String 会占用更多的内存较多的使用 Enum 会增加 DEX 文件的大小,会造成运行时更多的开销,使我们的应用需要更多的空间。特别是分dex的大APP,枚举的初始化很容易导致ANR

解决方案

既然是因为参数的类型太泛了造成的类型不安全,那么我只要将参数限定在某一个类型集合里面。

使用@IntDef/@StringDef + @interface来进行限定参数

build.gradle文件中添加依赖

dependencies { compile ‘com.android.support:support-annotations:24.2.0’ }

然后再使用,代码如下

public class SexTest { public final int MAN = 2; public final int WOMEN = 3; @IntDef({ MAN, WOMEN, }) //限定为MAN,WOMEN @Target(ElementType.PARAMETER) //表示注解作用范围,参数注解 @Retention(RetentionPolicy.SOURCE) //表示注解所存活的时间,在运行时,而不会存在. class 文件. public @interface Sex { //接口,定义新的注解类型 } public void setSex(@Sex int sex){ this.sex = sex; } public static void main(String[] args){ setSex(MAN); } }

如果我们尝试在调用setSex()方法的时候,传入不在限定之内的值,那么编译就不会通过,有错误提示。同理,我们也可以使用@StringDef。

转载请注明原文地址: https://www.6miu.com/read-2629812.html

最新回复(0)