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