初识枚举类,我们也许会提出疑问,枚举它是一种新的类型吗?不同于基本数据类型,引用
类型??为了更好地理解,我们从反编译一个enum类开始:
原java代码
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 ListgetEnumValues() { 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 list = getEnumValues(); for (Weather sw : list) { System.out.println(sw.value + "--" + sw.label); } } }
反编译之后:
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 }); } }
通过观察代码我们会发现enum关键字的含义其实就是使类被final修饰并继承抽象类Enum,它是java枚举类型的公共基本类,里面提供了一些
公共方法,同时对象Sunny、Rainy、Cloudy都是使用static final修饰的不可变引用,他们在静态块中被用new的方式实例化并初始化。因此
得出结论:实际上枚举类型就是以Java类来实现的,没有什么新的特点,只不过java编译器帮我们做了语法的解析和编译。同时反编译之后,
代码中还自动生成了两个方法values()和valueOf(String name),这两个方法存在于
java.lang.annotation.ElementType
类下面:
valueOf(String name)返回指定枚举常量
values()返回枚举类型的数据,用于遍历枚举
public enum Test { RED,YELLOW,GREEN,BLACK; public static void main(String[] args) { Test t[] = Test.values(); for (int i = 0; i < t.length; i++) { System.out.println(t[i] + ":" + t[i].ordinal()); } } }
结果:
RED:0 YELLOW:1 GREEN:2 BLACK:3
通过反编译也可以看出,枚举类其实就是简单的java类构成的,不过它已经继承了Enum类,由于单继承特性,他不能再继承
其它类了,但可以实现接口。
以下是一个含有抽象方法的枚举类:
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 ListgetEnumValues() { 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 list = getEnumValues(); for (Weather sw : list) { System.out.println(sw.value + "--" + sw.label + "--" + sw.test()); } } }
反编译之后:
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反编译文件:public final class Weather extends Enum
“含有抽象方法”的class反编译文件:public abstract class Weather extends Enum