Android代码替代枚举的正确之道

众所周知,在Android官方的性能优化相关课程中曾经提到使用枚举存在的性能问题,不建议在Android代码中使用枚举:

Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android

Effective Java中列举了使用枚举的众多优点,相对于Int静态常量来说,枚举最大的作用是提供了类型安全。看看如下的栗子:

class Person {
    public static final int MALE = 0;
    public static final int FEMALE = 1;

    private int sex;

    public void setSex(int sex) {
        this.sex = sex;
    }

    public String getSexDes() {
        if(sex == 0) {
            return "男";
        }else if(sex == 1){
            return "女";
        }else {
            throw new IllegalArgumentException("什么鬼性别?");
        }
    }
}

因为调用者可以在setSex()传递任何整数,那么导致出现了非男非女的性别,而使用枚举可以有效避免上述情况。

为了弥补Android平台不建议使用枚举的缺陷,官方推出了两个注解,IntDefStringDef,用来提供编译期的类型检查,使用灰常简单,下面以IntDef为栗:

首先,引入依赖包:

compile 'com.android.support:support-annotations:22.0.0'

然后就可以在代码中使用了:

public class MainActivity extends Activity {
public static final int MALE = 0;
public static final int FEMALE = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);
    Person person = new Person();
    person.setSex(MALE);
    ((Button) findViewById(R.id.test)).setText(person.getSexDes());
}
class Person {
    @SEX
    private int sex;
    public void setSex(@SEX int sex) {
        this.sex = sex;
    }
    @SEX
    public int getSex() {
        return sex;
    }
    public String getSexDes() {
        if (sex == MALE) {
            return "男";
        } else {
            return "女";
        }
    }
}

@IntDef({MALE, FEMALE})
@Retention(RetentionPolicy.SOURCE)
public @interface SEX {
}
}

这里我们可以看到,@SEX注解可以放到属性定义,参数,返回值等地方对数据类型进行限制。如果我们直接赋值一个Int参数给setSex(),IDE会直接报错:


Paste_Image.png

然而如果你曾经看过这篇文档,你就知道,这仅仅是AS的静态代码检查而已,就像上面的代码,尽管IDE已经报错,你还是可以直接Run Application,而且也可以成功运行。这倒是可以理解,因为我们这个注解本身就是RetentionPolicy.SOURCE,只能给代码检查工具使用。
它对应的AS代码检查项如下:


Paste_Image.png

在lint中,对应的选项是WrongConstant:

WrongConstant

Summary: Incorrect constant

Priority: 6 / 10
Severity: Error
Category: Security

Ensures that when parameter in a method only allows a specific set of
constants, calls obey those rules.

1、引入注解的support包,可以使用provided,避免打入正式发布的APK中。
2、对于是否替换Android中的枚举,需要分不同的情况,比如上文中提及的场景也是枚举使用的大部分场景:仅仅提供类型安全,那么我们可以考虑通过注解来替换;如果我们需要将数据和枚举常量关联起来,在枚举中声明域,然后编写一个带有数据的构造器,那么还是考虑把枚举留下吧。

参考:http://www.jianshu.com/p/f8ac84a3e3c1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值