说明:下面的反编译结果使用“http://download.csdn.net/detail/wangshuxuncom/6841823”处的反编译工具反编译的。
一、不含有抽象的方法
源码如下:
import java.util.Arrays;
import java.util.List;
public enum Weather {
Sunny(1, "晴天"), Rainy(2, "雨天"), Cloudy(3, "多云");
private int value;
private String label;
private Weather(int value, String label) {
this.value = value;
this.label = label;
}
public int getValue() {
return value;
}
public String getLabel() {
return label;
}
public static Weather parse(int value) {
Weather result = Weather.Sunny;
switch (value) {
case 1:
result = Weather.Sunny;
break;
case 2:
result = Weather.Rainy;
break;
case 3:
result = Weather.Cloudy;
break;
}
return result;
}
public static List<Weather> getEnumValues() {
return Arrays.asList(values());
}
public static void main(String[] args) {
System.out.println(Weather.Sunny.getValue() + ":" + Weather.Sunny.getLabel());
Weather weather = Weather.Cloudy;
System.out.println(weather.getValue() + ":" + weather.getLabel());
List<Weather> list = getEnumValues();
for (Weather sw : list) {
System.out.println(sw.value + "--" + sw.label);
}
}
}
反编译生成的class文件后的代码如下:
/*import java.io.PrintStream;*/
import java.util.*;
public final class Weather extends Enum{
private Weather(/*String s, int i,*/ int value, String label){
/*super(s, i);*/
this.value = value;
this.label = label;
}
public int getValue(){
return value;
}
public String getLabel(){
return label;
}
public static Weather parse(int value){
Weather result = Sunny;
switch(value){
case 1: /*// '\001'*/
result = Sunny;
break;
case 2: /*// '\002'*/
result = Rainy;
break;
case 3: /*// '\003'*/
result = Cloudy;
break;
}
return result;
}
public static List getEnumValues(){
return Arrays.asList(values());
}
public static void main(String args[]){
System.out.println((new StringBuilder(String.valueOf(Sunny.getValue()))).append(":").append(Sunny.getLabel()).toString());
Weather weather = Cloudy;
System.out.println((new StringBuilder(String.valueOf(weather.getValue()))).append(":").append(weather.getLabel()).toString());
List list = getEnumValues();
Weather sw;
for(Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println((new StringBuilder(String.valueOf(sw.value))).append("--").append(sw.label).toString()))
sw = (Weather)iterator.next();
}
/*public static Weather[] values(){
Weather aweather[];
int i;
Weather aweather1[];
System.arraycopy(aweather = ENUM$VALUES, 0, aweather1 = new Weather[i = aweather.length], 0, i);
return aweather1;
}*/
/*public static Weather valueOf(String s){
return (Weather)Enum.valueOf(Weather, s);
}*/
/*public static final Weather*/ Sunny;
/*public static final Weather*/ Rainy;
/*public static final Weather*/ Cloudy;
private int value;
private String label;
/*private static final Weather ENUM$VALUES[];*/
static {
Sunny = new Weather(/*"Sunny", 0,*/ 1, "\u6674\u5929");
Rainy = new Weather(/*"Rainy", 1,*/ 2, "\u96E8\u5929");
Cloudy = new Weather(/*"Cloudy", 2,*/ 3, "\u591A\u4E91");
/*ENUM$VALUES = (new Weather[] {
Sunny, Rainy, Cloudy
});*/
}
}
注意:所有/**/中间的东西都是多余的(/**/是人为添加的)
如何将反编译代码还原:
①、去掉被/**/掉的代码,去掉后代码如下:
import java.util.*;
public final class Weather extends Enum{
private Weather(int value, String label){
this.value = value;
this.label = label;
}
public int getValue(){
return value;
}
public String getLabel(){
return label;
}
public static Weather parse(int value){
Weather result = Sunny;
switch(value){
case 1:
result = Sunny;
break;
case 2:
result = Rainy;
break;
case 3:
result = Cloudy;
break;
}
return result;
}
public static List getEnumValues(){
return Arrays.asList(values());
}
public static void main(String args[]){
System.out.println((new StringBuilder(String.valueOf(Sunny.getValue()))).append(":").append(Sunny.getLabel()).toString());
Weather weather = Cloudy;
System.out.println((new StringBuilder(String.valueOf(weather.getValue()))).append(":").append(weather.getLabel()).toString());
List list = getEnumValues();
Weather sw;
for(Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println((new StringBuilder(String.valueOf(sw.value))).append("--").append(sw.label).toString()))
sw = (Weather)iterator.next();
}
Sunny;
Rainy;
Cloudy;
private int value;
private String label;
static {
Sunny = new Weather(1, "\u6674\u5929");
Rainy = new Weather(2, "\u96E8\u5929");
Cloudy = new Weather(3, "\u591A\u4E91");
}
}
②、在上一步的基础上对照非反编译中的java源码可以还原大概,呵呵呵,可能你会说“狗屁,我要是知道源码了,还反编译干什么”,呵呵呵,别急,如果你能把上面的这个弄明白了,你就会反编译没有源码参考的枚举类了。
③、呵呵呵,本来到此就可以了事了,可是还是禁不住提几个地方:注意反编译前java文件和反编译后生成的java文件在引类的区别;注意反编译class文件后的泛型没有了;从反编译的结果中可以得出这样的结论:实际上枚举类型就是以Java类来实现的,没有什么新的特点,只不过java编译器帮我们做了语法的解析和编译。
二、含有抽象的方法
源码如下:
import java.util.Arrays;
import java.util.List;
public enum Weather {
Sunny(1, "晴天") {
@Override
public String test() {
return "今天阳光明媚!!!\n";
}
},
Rainy(2, "雨天") {
@Override
public String test() {
return "出门别忘带把雨伞哦!!!\n";
}
},
Cloudy(3, "多云") {
@Override
public String test() {
return "别出去登高望远了,你看不远的,呵呵呵!!!\n";
}
};
private int value;
private String label;
private Weather(int value, String label) {
this.value = value;
this.label = label;
}
public int getValue() {
return value;
}
public String getLabel() {
return label;
}
public abstract String test();
public static Weather parse(int value) {
Weather result = Weather.Sunny;
switch (value) {
case 1:
result = Weather.Sunny;
break;
case 2:
result = Weather.Rainy;
break;
case 3:
result = Weather.Cloudy;
break;
}
return result;
}
public static List<Weather> getEnumValues() {
return Arrays.asList(values());
}
public static void main(String[] args) {
System.out.println(Weather.Sunny.getValue() + ":" + Weather.Sunny.getLabel());
Weather weather = Weather.Cloudy;
System.out.println(weather.getValue() + ":" + weather.getLabel() + "\n\n");
List<Weather> list = getEnumValues();
for (Weather sw : list) {
System.out.println(sw.value + "--" + sw.label + "--" + sw.test());
}
}
}
反编译生成的class文件后的代码如下:
import java.io.PrintStream;
import java.util.*;
public abstract class Weather extends Enum {
private Weather(String s, int i, int value, String label) {
super(s, i);
this.value = value;
this.label = label;
}
public int getValue() {
return value;
}
public String getLabel() {
return label;
}
public abstract String test();
public static Weather parse(int value) {
Weather result = Sunny;
switch (value) {
case 1: // '\001'
result = Sunny;
break;
case 2: // '\002'
result = Rainy;
break;
case 3: // '\003'
result = Cloudy;
break;
}
return result;
}
public static List getEnumValues() {
return Arrays.asList(values());
}
public static void main(String args[]) {
System.out.println((new StringBuilder(String.valueOf(Sunny.getValue()))).append(":").append(Sunny.getLabel()).toString());
Weather weather = Cloudy;
System.out.println((new StringBuilder(String.valueOf(weather.getValue()))).append(":").append(weather.getLabel()).append("\n\n").toString());
List list = getEnumValues();
Weather sw;
for (Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println((new StringBuilder(String.valueOf(sw.value))).append("--").append(sw.label).append("--").append(sw.test()).toString()))
sw = (Weather) iterator.next();
}
public static Weather[] values() {
Weather aweather[];
int i;
Weather aweather1[];
System.arraycopy(aweather = ENUM$VALUES, 0, aweather1 = new Weather[i = aweather.length], 0, i);
return aweather1;
}
public static Weather valueOf(String s) {
return (Weather) Enum.valueOf(Weather, s);
}
Weather(String s, int i, int j, String s1, Weather weather) {
this(s, i, j, s1);
}
public static final Weather Sunny;
public static final Weather Rainy;
public static final Weather Cloudy;
private int value;
private String label;
private static final Weather ENUM$VALUES[];
static {
Sunny = new Weather("Sunny", 0, 1, "\u6674\u5929") {
public String test() {
return "\u4ECA\u5929\u9633\u5149\u660E\u5A9A\uFF01\uFF01\uFF01\n";
}
};
Rainy = new Weather("Rainy", 1, 2, "\u96E8\u5929") {
public String test() {
return "\u51FA\u95E8\u522B\u5FD8\u5E26\u628A\u96E8\u4F1E\u54E6\uFF01\uFF01\uFF01\n";
}
};
Cloudy = new Weather("Cloudy", 2, 3, "\u591A\u4E91") {
public String test() {
return "\u522B\u51FA\u53BB\u767B\u9AD8\u671B\u8FDC\u4E86\uFF0C\u4F60\u770B\u4E0D\u8FDC\u7684\uFF0C\u5475\u5475\u5475\uFF01\uFF01\uFF01\n";
}
};
ENUM$VALUES = (new Weather[] { Sunny, Rainy, Cloudy });
}
}
总结:对比源代码和编译代码,找出他们的区别并不难,做到这一点就可以反编译含有抽象方法的枚举class文件,呵呵呵呵,将“不含抽象方法”的class反编译文件和“含有抽象方法”的class反编译文件,你应该还有一个很大的收获,呵呵呵,看着:
“不含抽象方法”的class反编译文件:public final class Weather extends Enum
“含有抽象方法”的class反编译文件:public abstractclass Weather extends Enum