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;
  }

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