枚举是java SE5中新增的特性,关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用。
我们知道,在android中应避免使用枚举,尽量用静态常量来代替枚举的使用,为何?有人会说了,因为枚举占用更多的内存。那为何枚举就比景太常量要占用更过的内存呢?
首先,我们来创建一个简单的枚举类EnumTest:
public enum EnumTest {
NAME,AGE
}
乍一看,完全不知从何看出它的具体实现,这时候我们试着用java命令javap -c来反编译其字节码看看:
先进入到目标文件的目录下, cd /.../JavaLearning/JavaLearingProject/src/com/sy/enums,然后通过命令 javac EnumTest.java得到EnumTest.class字节码文件,最后通过javap -c xx.class命令对其进行反编译,反编译后的输出为:
public final class com.sy.enums.EnumTest extends java.lang.Enum<com.sy.enums.EnumTest> {
public static final com.sy.enums.EnumTest NAME;
public static final com.sy.enums.EnumTest AGE;
public static com.sy.enums.EnumTest[] values();
Code:
0: getstatic #1 // Field $VALUES:[Lcom/sy/enums/EnumTest;
3: invokevirtual #2 // Method "[Lcom/sy/enums/EnumTest;".clone:()Ljava/lang/Object;
6: checkcast #3 // class "[Lcom/sy/enums/EnumTest;"
9: areturn
public static com.sy.enums.EnumTest valueOf(java.lang.String);
Code:
0: ldc #4 // class com/sy/enums/EnumTest
2: aload_0
3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
6: checkcast #4 // class com/sy/enums/EnumTest
9: areturn
static {};
Code:
0: new #4 // class com/sy/enums/EnumTest
3: dup
4: ldc #7 // String NAME
6: iconst_0
7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
10: putstatic #9 // Field NAME:Lcom/sy/enums/EnumTest;
13: new #4 // class com/sy/enums/EnumTest
16: dup
17: ldc #10 // String AGE
19: iconst_1
20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
23: putstatic #11 // Field AGE:Lcom/sy/enums/EnumTest;
26: iconst_2
27: anewarray #4 // class com/sy/enums/EnumTest
30: dup
31: iconst_0
32: getstatic #9 // Field NAME:Lcom/sy/enums/EnumTest;
35: aastore
36: dup
37: iconst_1
38: getstatic #11 // Field AGE:Lcom/sy/enums/EnumTest;
41: aastore
42: putstatic #1 // Field $VALUES:[Lcom/sy/enums/EnumTest;
45: return
}
从反编译后的代码可以看出,原来EnumTest继承自Enum,紧接着初始化了静态成员变量NAME、AGE,并且实例化了EnumTest的对象,光看到这里,就可以确定其占用的内存肯定大于单纯的使用静态常量所占用的内存。
什么,直接看反编译后的代码很蛋疼?没问题的,肯定有方便我们阅读的工具jad,下载完成解压后进入到jad目录下,会看到有可执行文件jad,通过./jad命令就可以对class字节码进行翻译并生成对应的java文件。
首先,我们也是先进入到jad目录下,cd /.../Desktop/dwonload/jad ,然后执行 ./jad -sjava /.../Desktop/github/JavaLearning/JavaLearingProject/src/com/sy/enums/EnumTest.class ,这一样会在jad目录下生成EnumTest.java文件,打开后如下:
public final class EnumTest extends Enum
{
public static EnumTest[] values()
{
return (EnumTest[])$VALUES.clone();
}
public static EnumTest valueOf(String s)
{
return (EnumTest)Enum.valueOf(com/sy/enums/EnumTest, s);
}
private EnumTest(String s, int i)
{
super(s, i);
}
public static final EnumTest NAME;
public static final EnumTest AGE;
private static final EnumTest $VALUES[];
static
{
NAME = new EnumTest("NAME", 0);
AGE = new EnumTest("AGE", 1);
$VALUES = (new EnumTest[] {
NAME, AGE
});
}
}
这样看一切就清晰了,我想看到这里大家都对enum有更深层次的理解了吧。