support-annotations @IntDef的使用(替代枚举)

1. 枚举利弊以及枚举倒底占多少内存

注:此部分内容转自Android是否推荐使用枚举(enum)?使用枚举的利弊以及枚举倒底占多少内存? 在此感谢分享

1.1 安卓中是否推荐使用枚举enum

Android 官方建议:
在这里插入图片描述
Android官网不建议使用enums,占用内存多(Enums often require more than twice as much memory as static constants.)。
Enum 需要占用较大的内存,如果对内存敏感,请尽量少使用 Enum,换用做静态常量。

1.2 利弊和占用内存

在Java1.5以前,我们要定义常量的话一般都是使用类常量或者接口常量
比如我们要定义4个颜色的常量。用类常量和枚举分别定义的话,就如下的实现方式:

//静态常量类
public class Color{
    public static final int COLOR_RED = 1;
    public static final int COLOR_GREEN = 2;
    public static final int COLOR_YELLOW = 3;
    public static final int COLOR_Blue = 4;
}
 //枚举常量类
public enum ColorEnum {
        RED, GREEN, YELLOW, BLUE;
    }

上面的代码中,我们分别定义了类常量和枚举常量。从定义上看,枚举常量显然更简单,让代码看起来更简洁,只要定义各个枚举项,而不需要定义值等。

安卓官方建议:Enums often require more than twice as much memory as static constants.

枚举一般需要比静态常量超过两倍多的内存。(具体对比请看原文 )

2.替换方案support-annotations

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

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

2.1 使用步骤

  1. 添加依赖(build.gradle)

    dependencies {
     // ...
     implementation 'com.android.support:support-annotations:28.0.0'
    }
    
  2. 使用详情

         private int weekDay;
    
         private static final int MONDAY = 1;
         private static final int TUESDAY = 2;
         private static final int WEDNESDAY = 3;
         private static final int THURSDAY = 4;
    
         @IntDef({MONDAY, TUESDAY, WEDNESDAY, THURSDAY})
         @Retention(RetentionPolicy.SOURCE)
         private @interface values {}
    
          //形参 weekDay 只能限定在MONDAY, TUESDAY, WEDNESDAY, THURSDAY 几个中
          private void setWeekDay(@values int weekDay) {
               this.weekDay= weekDay;W
          }
    
    

2.3 RetentionPolicy

  /**
  * Annotation retention policy.  The constants of this enumerated type
  * describe the various policies for retaining annotations.  They are used
  * in conjunction with the {@link Retention} meta-annotation type to specify
  * how long annotations are to be retained.
  *
  * @author  Joshua Bloch
  * @since 1.5
  */
  public enum RetentionPolicy {
     /** 
     * Annotations are to be discarded by the compiler.
     * 表明注解会被编译器丢弃,字节码中不会带有注解信息
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     * 表明注解会被写入字节码文件,且是@Retention的默认值
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     * 
     * 表明注解会被写入字节码文件,并且能够被JVM 在运行时获取到,可以通过反射的方式解析到
     *   
     * @see java.lang.reflect.AnnotatedElement
     */
     RUNTIME
 } 

2.4 常见使用

资源 注解
String资源ID @StringRes
图片资源ID @DrawableRes
动画资源ID @AnimatorRes
颜色资源ID @ColorRes
颜色值(AARRGGBB) @ColorInt
int值范围 @IntRange(from = 0, to = 100)

举例:

public void setTitle(@StringRes int titleResId) {
       getResources().getString(titleResId);
}

public void setColor(@ColorInt int color) {
     paint.setColor(color);
}

 public GlideRequest<TranscodeType> encodeQuality(@IntRange(from = 0, to = 100) int arg0) {
    if (getMutableOptions() instanceof GlideOptions) {
      this.requestOptions = ((GlideOptions) getMutableOptions()).encodeQuality(arg0);
    } else {
      this.requestOptions = new GlideOptions().apply(this.requestOptions).encodeQuality(arg0);
    }
    return this;
  }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章