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 使用步驟
-
添加依賴(
build.gradle
)dependencies { // ... implementation 'com.android.support:support-annotations:28.0.0' }
-
使用詳情
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;
}