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

作者: 楚云之南 | 来源:发表于2015-11-09 18:42 被阅读12556次

众所周知,在Android官方的性能优化相关课程中曾经提到使用枚举存在的性能问题,不建议在Android代码中使用枚举:
Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android

胡凯-The price of ENUMs

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.

OK,以上就是在Android代码中如何替换枚举类型的正确之道。
更新2015-11-10:

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

相关文章

  • Android小经验

    你应该知道的那些Android小经验 1.枚举提供类型安全 Android代码替代枚举的正确之道 2.匿名toke...

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

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

  • apt相关学习资料

    【Android开发@IntDef完美替代Enum (枚举)】https://www.jianshu.com/p/...

  • Android 尽量避免使用Enum

    Android之使用枚举利弊及替代方案 知识点: 概述 为什么要使用枚举? 使用 Enum 的缺点 解决方案 总结...

  • 性能

    @IntDef替代枚举 @IntDef/@StringDef本身是个Android中提供的一种注解. 添加依赖:c...

  • Android 注解替代枚举(enum)

    一、说明   笔记主要是记录一些本人在开发当中的学习和使用笔记。笔记内容包含一些本人觉得重要的知识点、本人易犯的错...

  • 替代枚举的注解

    Android中新引入的替代枚举的注解有IntDef和StringDef,这里以IntDef做例子说明一下.

  • Kotlin零基础学习 枚举

    枚举让代码变得更可读,容易理解。Android 用java语言很少写枚举, 因为Enum 需要占用较大的内存,所以...

  • Android中代替枚举的@IntDef用法

    IntDef本身是个Android中提供的一种注解,用于替代枚举的使用 定义static final的常量 定义一...

  • ReactNative Tips

    1、Android 6.0 Permission 正确的代码如下:

网友评论

本文标题:Android代码替代枚举的正确之道

本文链接:https://www.haomeiwen.com/subject/zdqhhttx.html