一、用作示例的枚举类
package com.meituan.huangdanyang;
public enum Operator {
ADD ("+") {
@Override
public int calculate(int a, int b) {
return a + b;
}
},
SUBTRACT ("-") {
@Override
public int calculate(int a, int b) {
return a - b;
}
},
MULTIPLY ("*") {
@Override
public int calculate(int a, int b) {
return a * b;
}
},
DIVIDE ("/") {
@Override
public int calculate(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("divisor must not be 0");
}
return a / b;
}
};
Operator (String operator) {
this.operator = operator;
}
private String operator;
public abstract int calculate(int a, int b);
public String getOperator() {
return operator;
}
}
使用时,ADD ("+")其实就是调用了Operator的构造函数Operator (String operator) ,初始化一个operator为"+"的Operator对象而已,并重写了抽象方法calculate。
我们可以这样使用;
int res = Operator.ADD.calculate(1,2);
System.out.println(res);
二、反编译
运行之后,找到Operator.class文件,先用javap -c Operator.class看看:
Last login: Fri Jul 20 17:03:29 on ttys005
admindeMacBook-Pro:huangdanyang hdychi$ javap -classpath . -c Operator.class
Compiled from "Operator.java"
public abstract class com.meituan.huangdanyang.Operator extends java.lang.Enum<com.meituan.huangdanyang.Operator> {
public static final com.meituan.huangdanyang.Operator ADD;
public static final com.meituan.huangdanyang.Operator SUBTRACT;
public static final com.meituan.huangdanyang.Operator MULTIPLY;
public static final com.meituan.huangdanyang.Operator DIVIDE;
public static com.meituan.huangdanyang.Operator[] values();
Code:
0: getstatic #2 // Field $VALUES:[Lcom/meituan/huangdanyang/Operator;
3: invokevirtual #3 // Method "[Lcom/meituan/huangdanyang/Operator;".clone:()Ljava/lang/Object;
6: checkcast #4 // class "[Lcom/meituan/huangdanyang/Operator;"
9: areturn
public static com.meituan.huangdanyang.Operator valueOf(java.lang.String);
Code:
0: ldc #5 // class com/meituan/huangdanyang/Operator
2: aload_0
3: invokestatic #6 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
6: checkcast #5 // class com/meituan/huangdanyang/Operator
9: areturn
public abstract int calculate(int, int);
public java.lang.String getOperator();
Code:
0: aload_0
1: getfield #8 // Field operator:Ljava/lang/String;
4: areturn
com.meituan.huangdanyang.Operator(java.lang.String, int, java.lang.String, com.meituan.huangdanyang.Operator$1);
Code:
0: aload_0
1: aload_1
2: iload_2
3: aload_3
4: invokespecial #1 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
7: return
static {};
Code:
0: new #9 // class com/meituan/huangdanyang/Operator$1
3: dup
4: ldc #10 // String ADD
6: iconst_0
7: ldc #11 // String +
9: invokespecial #12 // Method com/meituan/huangdanyang/Operator$1."<init>":(Ljava/lang/String;ILjava/lang/String;)V
12: putstatic #13 // Field ADD:Lcom/meituan/huangdanyang/Operator;
15: new #14 // class com/meituan/huangdanyang/Operator$2
18: dup
19: ldc #15 // String SUBTRACT
21: iconst_1
22: ldc #16 // String -
24: invokespecial #17 // Method com/meituan/huangdanyang/Operator$2."<init>":(Ljava/lang/String;ILjava/lang/String;)V
27: putstatic #18 // Field SUBTRACT:Lcom/meituan/huangdanyang/Operator;
30: new #19 // class com/meituan/huangdanyang/Operator$3
33: dup
34: ldc #20 // String MULTIPLY
36: iconst_2
37: ldc #21 // String *
39: invokespecial #22 // Method com/meituan/huangdanyang/Operator$3."<init>":(Ljava/lang/String;ILjava/lang/String;)V
42: putstatic #23 // Field MULTIPLY:Lcom/meituan/huangdanyang/Operator;
45: new #24 // class com/meituan/huangdanyang/Operator$4
48: dup
49: ldc #25 // String DIVIDE
51: iconst_3
52: ldc #26 // String /
54: invokespecial #27 // Method com/meituan/huangdanyang/Operator$4."<init>":(Ljava/lang/String;ILjava/lang/String;)V
57: putstatic #28 // Field DIVIDE:Lcom/meituan/huangdanyang/Operator;
60: iconst_4
61: anewarray #5 // class com/meituan/huangdanyang/Operator
64: dup
65: iconst_0
66: getstatic #13 // Field ADD:Lcom/meituan/huangdanyang/Operator;
69: aastore
70: dup
71: iconst_1
72: getstatic #18 // Field SUBTRACT:Lcom/meituan/huangdanyang/Operator;
75: aastore
76: dup
77: iconst_2
78: getstatic #23 // Field MULTIPLY:Lcom/meituan/huangdanyang/Operator;
81: aastore
82: dup
83: iconst_3
84: getstatic #28 // Field DIVIDE:Lcom/meituan/huangdanyang/Operator;
87: aastore
88: putstatic #2 // Field $VALUES:[Lcom/meituan/huangdanyang/Operator;
91: return
}
笔者太菜了,看不懂。
![](https://img.haomeiwen.com/i11069961/fec15feaf2afaf43.jpeg)
还是来用一个好使的工具,jad,来把class文件反编译成一个java文件。
http://www.javadecompilers.com/jad
然后,./jad -sjava Operator.class
在当前命令行所在目录生成了Operator.java文件
Operator.java:
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Operator.java
package com.meituan.huangdanyang;
public abstract class Operator extends Enum
{
public static Operator[] values()
{
return (Operator[])$VALUES.clone();
}
public static Operator valueOf(String name)
{
return (Operator)Enum.valueOf(com/meituan/huangdanyang/Operator, name);
}
private Operator(String s, int i, String operator)
{
super(s, i);
this.operator = operator;
}
public abstract int calculate(int i, int j);
public String getOperator()
{
return operator;
}
public static final Operator ADD;
public static final Operator SUBTRACT;
public static final Operator MULTIPLY;
public static final Operator DIVIDE;
private String operator;
private static final Operator $VALUES[];
static
{
ADD = new Operator("ADD", 0, "+") {
public int calculate(int a, int b)
{
return a + b;
}
}
;
SUBTRACT = new Operator("SUBTRACT", 1, "-") {
public int calculate(int a, int b)
{
return a - b;
}
}
;
MULTIPLY = new Operator("MULTIPLY", 2, "*") {
public int calculate(int a, int b)
{
return a * b;
}
}
;
DIVIDE = new Operator("DIVIDE", 3, "/") {
public int calculate(int a, int b)
{
if(b == 0)
throw new IllegalArgumentException("divisor must not be 0");
else
return a / b;
}
}
;
$VALUES = (new Operator[] {
ADD, SUBTRACT, MULTIPLY, DIVIDE
});
}
}
可以看到,ADD、SUBSTRACT这四个,被编译成静态Operator对象,并且在静态区添加了代码,使用了内部类的方法,对四个常量进行了初始化。由于使用了内部类,在编译时还会产生Operator1.class,Operator2.class,Operator3.class,Operator4.class。
再次利用jad,反编译处java文件,打开:
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Operator.java
package com.meituan.huangdanyang;
// Referenced classes of package com.meituan.huangdanyang:
// Operator
static class Operator$1 extends Operator
{
public int calculate(int a, int b)
{
return a + b;
}
Operator$1(String s, int i, String operator)
{
super(s, i, operator, null);
}
}
就是一个静态内部类,实现了calculate方法。
同时为了满足Enum类都具有的values方法和valueOf方法,编译的时候,添加了一个$VALUES Operator数组,把枚举里的元素存入这个数组中,在调用values方法时就可以clone这个枚举里的元素。
网友评论