问:enum 算不算基本数据类型答:不算,enum是引用类型。
Java中的基本数据类型只有8种,分别是byte、short、int、long、float、double、char、boolean
在 Java5之后新增的 Enum属于引用类型,跟 String一样也是属于类。好奇的同学可能有疑问,既然说 enum是引用类型,为何在使用的时候没有见到类呢?
enum的使用场景
我们先来看一个简单的enum使用场景,
public class DayDemo { public enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY } public static void main(String[] args) { }}
这里面只定义了一个枚举类型 Day,通过枚举定义了周一到周四四种类型,后续我们使用的时候就可以直接用 Day.MONDAY 这样的方式来使用枚举值了。
为什么说枚举是类
在这代码里没有声明类,也没用其他的引用,那么来看看编译后的结果
$ ls'DayDemo$Day.class' DayDemo.class DayDemo.java
可以看到多了一个叫 DayDemo$Day.class的类出来,从 class文件可以看出, 枚举 Day编译成了一个类,从这里可以断定虽然我们没有定义这个类,但是编译器会把枚举作为类进行编译,从某种角度上来说 enum是一种语法糖,现在来看一下 class文件的构造,
public final class DayDemo$Day extends java.lang.Enum<DayDemo$Day> { public static final DayDemo$Day MONDAY; public static final DayDemo$Day TUESDAY; public static final DayDemo$Day WEDNESDAY; public static final DayDemo$Day THURSDAY; public static DayDemo$Day[] values(); Code: 0: getstatic #1 // Field $VALUES:[LDayDemo$Day; 3: invokevirtual #2 // Method "[LDayDemo$Day;".clone:()Ljava/lang/Object; 6: checkcast #3 // class "[LDayDemo$Day;" 9: areturn public static DayDemo$Day valueOf(java.lang.String); Code: 0: ldc #4 // class DayDemo$Day 2: aload_0 3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; 6: checkcast #4 // class DayDemo$Day 9: areturn static {}; Code: 0: new #4 // class DayDemo$Day 3: dup 4: ldc #7 // String MONDAY 6: iconst_0 7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 10: putstatic #9 // Field MONDAY:LDayDemo$Day; 13: new #4 // class DayDemo$Day 16: dup 17: ldc #10 // String TUESDAY 19: iconst_1 20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 23: putstatic #11 // Field TUESDAY:LDayDemo$Day; 26: new #4 // class DayDemo$Day 29: dup 30: ldc #12 // String WEDNESDAY 32: iconst_2 33: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 36: putstatic #13 // Field WEDNESDAY:LDayDemo$Day; 39: new #4 // class DayDemo$Day 42: dup 43: ldc #14 // String THURSDAY 45: iconst_3 46: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 49: putstatic #15 // Field THURSDAY:LDayDemo$Day; 52: iconst_4 53: anewarray #4 // class DayDemo$Day 56: dup 57: iconst_0 58: getstatic #9 // Field MONDAY:LDayDemo$Day; 61: aastore 62: dup 63: iconst_1 64: getstatic #11 // Field TUESDAY:LDayDemo$Day; 67: aastore 68: dup 69: iconst_2 70: getstatic #13 // Field WEDNESDAY:LDayDemo$Day; 73: aastore 74: dup 75: iconst_3 76: getstatic #15 // Field THURSDAY:LDayDemo$Day; 79: aastore 80: putstatic #1 // Field $VALUES:[LDayDemo$Day; 83: return}
如果上面的代码不够简洁易懂的话可以看看下面翻译后的代码,这只翻译 static代码段,其他的像 values和 valueOf都比较简单,
static { //实例化枚举实例 MONDAY = new Day("MONDAY", 0); TUESDAY = new Day("TUESDAY", 1); WEDNESDAY = new Day("WEDNESDAY", 2); THURSDAY = new Day("THURSDAY", 3); $VALUES = (new Day[] { MONDAY, TUESDAY, WEDNESDAY, THURSDAY }); }
总结
把这段代码和上面反编译的结果一起看的话就可以明白,枚举类型在编译后会作为一个类生成,编译器会帮我们插入 values和 valueOf 两个方法,同时生成 final的常量,在生成的静态代码段里会实例化好对应的枚举实例,换句话说,我们所定义的每个枚举类,最终都会在它里面生成对应的静态常量,而常量的值就是我们所定义的值的String串。