java枚举类:
public enum Animal {
Dog,
Pig,
Fish
}
javap -p Animal.class:
public final class main.com.example.test.Animal extends java.lang.Enum<main.com.example.test.Animal> {
public static final main.com.example.test.Animal Dog;
public static final main.com.example.test.Animal Pig;
public static final main.com.example.test.Animal Fish;
private static final main.com.example.test.Animal[] $VALUES;
public static main.com.example.test.Animal[] values();
public static main.com.example.test.Animal valueOf(java.lang.String);
private main.com.example.test.Animal();
static {};
}
- Animal继承Enum
- 每个枚举值都是静态变量
javap -c Animal.class
public final class main.com.example.test.Animal extends java.lang.Enum<main.com.example.test.Animal> {
public static final main.com.example.test.Animal Dog;
public static final main.com.example.test.Animal Pig;
public static final main.com.example.test.Animal Fish;
public static main.com.example.test.Animal[] values();
Code:
0: getstatic #1 // Field $VALUES:[Lmain/com/example/test/Animal;
3: invokevirtual #2 // Method "[Lmain/com/example/test/Animal;".clone:()Ljava/lang/Object;
6: checkcast #3 // class "[Lmain/com/example/test/Animal;"
9: areturn
public static main.com.example.test.Animal valueOf(java.lang.String);
Code:
0: ldc #4 // class main/com/example/test/Animal
2: aload_0
3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
6: checkcast #4 // class main/com/example/test/Animal
9: areturn
static {};
Code:
0: new #4 // class main/com/example/test/Animal
3: dup
4: ldc #7 // String Dog
6: iconst_0
7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
10: putstatic #9 // Field Dog:Lmain/com/example/test/Animal;
13: new #4 // class main/com/example/test/Animal
16: dup
17: ldc #10 // String Pig
19: iconst_1
20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
23: putstatic #11 // Field Pig:Lmain/com/example/test/Animal;
26: new #4 // class main/com/example/test/Animal
29: dup
30: ldc #12 // String Fish
32: iconst_2
33: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
36: putstatic #13 // Field Fish:Lmain/com/example/test/Animal;
39: iconst_3
40: anewarray #4 // class main/com/example/test/Animal
43: dup
44: iconst_0
45: getstatic #9 // Field Dog:Lmain/com/example/test/Animal;
48: aastore
49: dup
50: iconst_1
51: getstatic #11 // Field Pig:Lmain/com/example/test/Animal;
54: aastore
55: dup
56: iconst_2
57: getstatic #13 // Field Fish:Lmain/com/example/test/Animal;
60: aastore
61: putstatic #1 // Field $VALUES:[Lmain/com/example/test/Animal;
64: return
}
-
在static代码块中会对每个枚举值进行初始化
-
$VALUES是一个静态变量,是枚举值数组,在static代码块中进行初始化和添加
-
values()方法返回的就是$VALUES数组的拷贝,浅拷贝
-
valuesOf()方法根据字符串返回对应的枚举值,调用了Enum.valueOf()方法:
//Enum.java public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) { T result = enumType.enumConstantDirectory().get(name); if (result != null) return result; if (name == null) throw new NullPointerException("Name is null"); throw new IllegalArgumentException( "No enum constant " + enumType.getCanonicalName() + "." + name); }enumConstantDirectory的来源可以看Class的源码:
Map<String, T> enumConstantDirectory() { Map<String, T> directory = enumConstantDirectory; if (directory == null) { T[] universe = getEnumConstantsShared(); if (universe == null) throw new IllegalArgumentException( getName() + " is not an enum type"); directory = new HashMap<>((int)(universe.length / 0.75f) + 1); for (T constant : universe) { directory.put(((Enum<?>)constant).name(), constant); } enumConstantDirectory = directory; } return directory; }getEnumConstantsShared()方法也在Class.java中:
T[] getEnumConstantsShared() { T[] constants = enumConstants; if (constants == null) { if (!isEnum()) return null; try { final Method values = getMethod("values"); java.security.AccessController.doPrivileged( new java.security.PrivilegedAction<>() { public Void run() { values.setAccessible(true); return null; } }); @SuppressWarnings("unchecked") T[] temporaryConstants = (T[])values.invoke(null); enumConstants = constants = temporaryConstants; } // These can happen when users concoct enum-like classes // that don't comply with the enum spec. catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException ex) { return null; } } return constants; }所以可以看到是通过反射调用枚举类中的values()方法得到枚举值的数组,然后生成一个HashMap映射表