深入理解枚举

枚举是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有更深层次的理解了吧。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fastsy

打赏一份隆江猪脚饭吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值