• 慎用枚举类型 因为枚举更占内存
  • 发布于 2个月前
  • 327 热度
    0 评论
  • 林勇
  • 0 粉丝 38 篇博客
  •   
从以前学习java 开始就听说枚举很占内存,然后老版Android开发指南文章也指出,枚举通常需要比静态常量多两倍的内存。你应该严格避免在android上使用枚举。那么究竟为什么说枚举更占内存呢?本文就是通过这种方法来分析枚举为什么占内存的,而不是说拒绝枚举。

关于 Enum
Enum 一般用来表示一组相同类型可列举的常量。如性别、日期、月份、颜色等。对这些属性用常量的好处是显而易见的,不仅可以保证单例,且比较时候可以用 ”==” 来替换 equals 。

基本使用
看看枚举的基本使用
public enum Color {   
  RED , BLUE,GREEN,BLACK ;   
}
原理分析

通常会使用javap -c Color.class 反编译class 文件,查看生成的字节码,如下:
Compiled from "Color.java"
public final class org.fast.clean.Color extends java.lang.Enum<org.fast.clean.Color> {
  public static final org.fast.clean.Color RED;
  public static final org.fast.clean.Color BLUE;
  public static final org.fast.clean.Color GREEN;
  public static final org.fast.clean.Color BLACK;
  public static org.fast.clean.Color[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[Lorg/fast/clean/Color;
       3: invokevirtual #2                  // Method "[Lorg/fast/clean/Color;".clone:()Ljava/lang/Object;
       6: checkcast     #3                  // class "[Lorg/fast/clean/Color;"
       9: areturn

  public static org.fast.clean.Color valueOf(java.lang.String);
    Code:
     ....
            9: areturn

  static {};
    Code:
       0: new           #4                  // class org/fast/clean/Color
       3: dup
       4: ldc           #7                  // String RED
       6: iconst_0
       7: invokespecial #8                  // Method "<init>":(Ljava/lang/
       ....
      10: putstatic     #9                  // Field RED:Lorg/fast/clean/Color;
      13: new           #4                  // class org/fast/clean/Color
      16: dup
      17: ldc           #10                 // String BLUE
          83: return
}
org.fast.clean.Color 类被编译成继承自继承自java.lang.Enum的final类,其中的成员变量也是final常量,它们都不能被修改的。
下面使用jad 反编译生成jad源码文件, 文件显示每个方法的字节码的实际作用,与源码做出对比。
public final class Color extends Enum
{
    public static Color[] values()
    {
        return (Color[])$VALUES.clone();
    }
    public static Color valueOf(String s)
    {
        return (Color)Enum.valueOf(org/fast/clean/Color, s);
    }
    private Color(String s, int i)
    {
        super(s, i);
    }
    public static final Color RED;
    public static final Color BLUE;
    public static final Color GREEN;
    public static final Color BLACK;
    private static final Color $VALUES[];
    static 
    {
        RED = new Color("RED", 0);
        BLUE = new Color("BLUE", 1);
        GREEN = new Color("GREEN", 2);
        BLACK = new Color("BLACK", 3);
        $VALUES = (new Color[] {
            RED, BLUE, GREEN, BLACK
        });
    }
}
通过比较字节码和源代码的区别,我们可以知道为什么枚举确实比简单的静态变量占用的内存要更多。
用户评论