原理
那我们定义枚举类型后,到底发生了什么呢?我们对枚举的实现原理进行探究。
我们来解析下Color.class文件,命令javap Color
public final class Color extends java.lang.Enum<Color> { public static final Color Red; public static final Color Blue; public static final Color Green; public static final Color[] $VALUES; public static Color[] values(); public static Color valueOf(java.lang.String); static {}; }
从解析后的文件中我们可以知道
1.枚举类是final
的,不能被继承
2.枚举类在经过编译后生成一个继承java.lang.Enum
的类 Color
3.编译后的枚举值,是该类的Color类型的成员变量,如 Red、Bule、Green
,并且是final static
修饰
4.枚举编译后的类添加了静态的values()
和valueOf(java.lang.String)
方法
5.静态代码块static {}
进一步细化Color.class
命令javap -c Color
public final class Color extends java.lang.Enum<Color> { public static final Color Red; public static final Color Blue; public static final Color Green; public static Color[] values(); Code: 0: getstatic #1 // Field $VALUES:[LColor; 3: invokevirtual #2 // Method "[LColor;".clone:()Ljava/lang/Object; 6: checkcast #3 // class "[LColor;" 9: areturn public static Color valueOf(java.lang.String); Code: 0: ldc #4 // class Color 2: aload_0 3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljav a/lang/Enum; 6: checkcast #4 // class Color 9: areturn static {}; Code: 0: new #4 // class Color 3: dup 4: ldc #7 // String Red 6: iconst_0 7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 10: putstatic #9 // Field Red:LColor; 13: new #4 // class Color 16: dup 17: ldc #10 // String Blue 19: iconst_1 20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 23: putstatic #11 // Field Blue:LColor; 26: new #4 // class Color 29: dup 30: ldc #12 // String Green 32: iconst_2 33: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 36: putstatic #13 // Field Green:LColor; 39: iconst_3 40: anewarray #4 // class Color 43: dup 44: iconst_0 45: getstatic #9 // Field Red:LColor; 48: aastore 49: dup 50: iconst_1 51: getstatic #11 // Field Blue:LColor; 54: aastore 55: dup 56: iconst_2 57: getstatic #13 // Field Green:LColor; 60: aastore 61: putstatic #1 // Field $VALUES:[LColor; 64: return }
还原后的代码如下:
public final class Color extends java.lang.Enum<Color> { //定义的枚举成员 public static final Color Red; public static final Color Blue; public static final Color Green; //编译器自动生成的 javap -c 还查不出来,疑惑 public static final /* synthetic */ Color[] $VALUES;//编译器自动生成的 public static Color[] values(){ /** * 0: getstatic #1 // Field $VALUES:[LColor; * 3: invokevirtual #2 // Method "[LColor;".clone:()Ljava/lang/Object; * 6: checkcast #3 // class "[LColor;" * 9: areturn */ return $VALUES.clone(); } public static Color valueOf(java.lang.String s){ /** * 0: ldc #4 // class Color * 2: aload_0 * 3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljav * a/lang/Enum; * 6: checkcast #4 // class Color * 9: areturn */ return Enum.valueOf(Color.class,s); } protected Color(String name, int ordinal) { super(name, ordinal); } static { /** * 0: new #4 // class Color * 3: dup * 4: ldc #7 // String Red * 6: iconst_0 * 7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V * 10: putstatic #9 // Field Red:LColor; */ Red=new Color("Red",0); /** * 13: new #4 // class Color * 16: dup * 17: ldc #10 // String Blue * 19: iconst_1 * 20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V * 23: putstatic #11 // Field Blue:LColor; */ Blue=new Color("Blue",1); /** * 26: new #4 // class Color * 29: dup * 30: ldc #12 // String Green * 32: iconst_2 * 33: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V * 36: putstatic #13 // Field Green:LColor; */ Green=new Color("Green",2); /** * 39: iconst_3 * 40: anewarray #4 // class Color * 43: dup * 44: iconst_0 * 45: getstatic #9 // Field Red:LColor; * 48: aastore * 49: dup * 50: iconst_1 * 51: getstatic #11 // Field Blue:LColor; * 54: aastore * 55: dup * 56: iconst_2 * 57: getstatic #13 // Field Green:LColor; * 60: aastore * 61: putstatic #1 // Field $VALUES:[LColor; */ $VALUES=new Color[]{Red,Blue,Green}; };