美文网首页
使用@IntDef和@StringDef代替Java枚举

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

作者: 爵小友 | 来源:发表于2017-12-13 11:21 被阅读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可以保留多长时间:

    • RetentionPolicy.CLASS 默认值,编译器将把Annotation记录在class文件中。当运行Java程序时,JVM不再保留Annotation。
    • RetentionPolicy.RUNTIME 编译器将把Annotation记录在class文件中。当运行Java程序时,JVM也会保留Annotation。程序可以通过反射获取该Annotation信息。
    • RetentionPolicy.SOURCE Annotation只保留在源代码中,编译器直接丢弃这种Annotation。

    接下来我们使用的时候:

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

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

    参考

    相关文章

      网友评论

          本文标题:使用@IntDef和@StringDef代替Java枚举

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