之前一直忽视的一个知识点,最近由于时间比较多,就干脆整理整理这些知识点,毕竟枚举也是平时使用的比较多的东西。
1. 本人参与的项目中的枚举使用例子如下:
public interface TestEnum {
enum Status {
Success(0, "成功"),
Failed(1, "失败");
private Integer _value;
private String _name;
private Status(Integer value, String name) {
_value = value;
_name = name;
}
public Integer getValue() {
return _value;
}
public String getName() {
return _name;
}
public static Map<Integer, String> getMap() {
Map<Integer, String> maps = new HashMap<Integer, String>();
for (Status v : Status.values()) {
maps.put(v.getValue(), v.getName());
}
return maps;
}
}
}
2.查看编译之后的文件:
TestEnum自然不必说,但是关于Status的实现是通过一个内部类来操控的。
3.反编译结果1
这边我们能发现几个信息:
3.1 Success和Failed的类型是枚举类Status类型,而且均是static final修饰的(这个和我们平时在一个类中使用定义一些全局变量差不多形式)。
3.2 添加了values和valueof两个方法。
3.3 最后存在一个静态代码块(注意一下静态代码块的作用)。不熟悉的可以看传送门。
3.4 对于枚举类Status来说,它是继承了Java提供的枚举类Enum,也就意味着我们自定义的枚举类是不能去继承别的类的。
4.反编译详情
D:\>javap -c -v TestEnum$Status.class
Classfile /D:/TestEnum$Status.class
Last modified 2018-7-18; size 1759 bytes
MD5 checksum a512ccc5c2682f5290a30b333990f6b1
Compiled from "TestEnum.java"
public final class TestEnum$Status extends java.lang.Enum<TestEnum$Status>
Signature: #57 // Ljava/lang/Enum<LTestEnum$Status;>;
SourceFile: "TestEnum.java"
InnerClasses:
public static final #25= #4 of #63; //Status=class TestEnum$Status of cla
ss TestEnum
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
Constant pool:
....省略
{
public static final TestEnum$Status Success;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
public static final TestEnum$Status Failed;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
public static TestEnum$Status[] values();
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: getstatic #1 // Field $VALUES:[LTestEnum$Status
;
3: invokevirtual #2 // Method "[LTestEnum$Status;".clo
ne:()Ljava/lang/Object;
6: checkcast #3 // class "[LTestEnum$Status;"
9: areturn
LineNumberTable:
line 12: 0
public static TestEnum$Status valueOf(java.lang.String);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: ldc_w #4 // class TestEnum$Status
3: aload_0
4: invokestatic #5 // Method java/lang/Enum.valueOf:(
Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
7: checkcast #4 // class TestEnum$Status
10: areturn
LineNumberTable:
line 12: 0
public java.lang.Integer value();
flags: ACC_PUBLIC
Code:
....省略,不是重点
LineNumberTable:
line 25: 0
public java.lang.String getName();
flags: ACC_PUBLIC
Code:
....省略,不是重点
LineNumberTable:
line 28: 0
public static java.util.Map<java.lang.Integer, java.lang.String> mapAll();
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=5, args_size=0
....省略,不是重点
er;Ljava/lang/String;>;
static {};
flags: ACC_STATIC
Code:
stack=6, locals=0, args_size=0
0: new #4 // class TestEnum$Status
3: dup
4: ldc #15 // String Success
6: iconst_0
7: iconst_0
8: invokestatic #16 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
11: ldc #17 // String 鎴愬姛
13: invokespecial #18 // Method "<init>":(Ljava/lang/Str
ing;ILjava/lang/Integer;Ljava/lang/String;)V
16: putstatic #19 // Field Success:LTestEnum$Status;
19: new #4 // class TestEnum$Status
22: dup
23: ldc #20 // String Failed
25: iconst_1
26: iconst_1
27: invokestatic #16 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
30: ldc #21 // String 澶辫触
32: invokespecial #18 // Method "<init>":(Ljava/lang/Str
ing;ILjava/lang/Integer;Ljava/lang/String;)V
35: putstatic #22 // Field Failed:LTestEnum$Status;
38: iconst_2
39: anewarray #4 // class TestEnum$Status
42: dup
43: iconst_0
44: getstatic #19 // Field Success:LTestEnum$Status;
47: aastore
48: dup
49: iconst_1
50: getstatic #22 // Field Failed:LTestEnum$Status;
53: aastore
54: putstatic #1 // Field $VALUES:[LTestEnum$Status
;
57: return
LineNumberTable:
line 13: 0
line 14: 19
line 12: 38
}
4.1 valueof方法的底层调用还是Enum类里面提供的valueof方法。
4.2 静态代码块中执行了Success和Failed的初始化操作,这就表示在类加载的时候枚举的值就确定了。