众所周知,在Android中使用Enum枚举会极大的影响 性能,内存消耗大。原因如下:
Android官方文档中也有说明,enum中的每一个值其实都是一个Object对象,每声明一个值就会创建一部分的内存以使它能够被引用到这个对象,相比于静态常量,enum会花费近2倍的内存空间。
通常使用定义静态常量来代替Enum使用,如下:
public class XXConstant{
public static final int TYPE_ONE = 1;
public static final int TYPE_TWO = 2;
...
}
但是这种方式在用户不了解就会出现取值范围不清楚的问题,调用者在不知道源码的情况下有可能会导致传值错误,而且也不知道从何处找到该常量,为了解决这种方式google官方提供了另外一种很好的解决方式。
废话不多说,直接上例子,大家一看就明白
public class NetTypeUtil {
public static final int STRING_4G = 0;
public static final int STRING_3G = 1;
public static final int STRING_2G = 2;
public static final int STRING_WIFI = 3;
public static final int STRING_UNKNOWN = 4;
@IntDef({STRING_4G,STRING_3G,STRING_2G,STRING_WIFI,STRING_UNKNOWN})
@Retention(RetentionPolicy.SOURCE)
public @interface NetWorkStatus{}
public static String getNetWorkString(@NetWorkStatus int type) {
if (type == STRING_4G) {
return "NETWORK_4G";
} else if (type == STRING_3G) {
return "NETWORK_3G";
} else if (type == STRING_2G) {
return "NETWORK_2G";
} else if (type == STRING_WIFI) {
return "NETWORK_wifi";
} else {
return "unknown";
}
}
}
其中@IntDef就是定义了要用到的几个固定常量,@Retention注解包含有3个值分别是RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME,其中SOURCE意思就是告诉编辑器在生存.class文件时不保留枚举注解数据,CLASS意思是告诉编辑器在生成.class文件时保留注解数据,但在vm运行时不保留;RUNTIME意思告诉编辑器生成.class文件时保留注解数据,vm运行时一直存在。详见源码描述:
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.
*/
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.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
好了,回到正题。当我们使用的时候调用NetTypeUtil.getNetWorkString()传递参数时,如果传int类型数据就会报错,给出可传递的值得范围,提高了可读和可维护性。
如果在需要用大量的Enum时,用这种方式替换相信内存占用及性能会好很多,而且也是google官方推荐的。