使用@IntDef和@StringDef代替Java枚举

2017-12-13  本文已影响222人  爵小友

最近看别人的代码,发现别人使用了@IntDef的注解,便上网搜了一圈记录下来。

定义

Google文档是这样说的

Use the @IntDef and @StringDef annotations so you can create enumerated annotations of integer and string sets to validate other types of code references. Typedef annotations ensure that a particular parameter, return value, or field references a specific set of constants. They also enable code completion to automatically offer the allowed constants.

就是可以通过@IntDef和@StringDef创建枚举注解来验证你的代码引用是否正确,编译器自动检查也会对此校验。

使用

一般我们用静态常量来替代枚举,比如一年四季,一周七天,九大行星,七大洲等这些固定的值:

    public static final int SPRING = 1;
    public static final int SUMMER = 2;
    public static final int AUTUMN = 3;
    public static final int WINTER = 4;

但是这样写有些小问题,设置季节的时候可以设置任意int值,导致程序的健壮性不是很好。所以就引出了枚举:

    enum Season {
        SPRING, SUMMER, AUTUMN, WINTER
    }

这样setSeason()就不会设置成其他值,只能是枚举中的其中一个值。
但是各种Android性能优化告诉我们,尽量少用枚举,枚举消耗的内存比定义成常量更多。(其实少用点枚举也没多大关系,只有在内存紧张的时候才会考虑),因此,谷歌就推出了@IntDef和@StringDef注解。

首先,加入依赖:

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

然后,定义静态常量:

    public static final int SPRING = 1;
    public static final int SUMMER = 2;
    public static final int AUTUMN = 3;
    public static final int WINTER = 4;

为这些常量声明@IntDef:

    @IntDef({SPRING, SUMMER,AUTUMN,WINTER})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Season {}

@Retention是Java里的注解内容,用于指定被修饰的Annotation可以保留多长时间:

接下来我们使用的时候:

    @Season int currentDay ;

    public void setCurrentDay(@Season int currentDay) {
        this.currentDay = currentDay;
    }
 
    @Season
    public int getCurrentDay() {
      return currentDay;
    }

这样就完成了,既不用枚举,常量也不会乱定义的问题。@StringDef用法一样,就是常量定义的是String类型。

参考

上一篇 下一篇

猜你喜欢

热点阅读