Java枚举类型
java从JDK1.5开始支持枚举,也就是说,Java一开始是不支持枚举的,就像泛型一样,都是JDK1.5才加入的新特性。通常一个特性如果在一开始没有提供,在语言发展后期才添加,会遇到一个问题,就是向后兼容性的问题。像Java在1.5中引入的很多特性,为了向后兼容,编译器会帮我们写的源代码做很多事情,比如泛型为什么会擦除类型,为什么会生成桥接方法,foreach迭代,自动装箱/拆箱等,这有个术语叫“语法糖”,而编译器的特殊处理叫“解语法糖”。那么像枚举也是在JDK1.5中才引入的,又是怎么实现的呢?
Java在1.5中添加了java.lang.Enum抽象类,它是所有枚举类型基类。提供了一些基础属性和基础方法。同时,对把枚举用作Set和Map也提供了支持,即java.util.EnumSet和java.util.EnumMap。
一、枚举类型
枚举类型在java语言中是一种基本数据类型而不是构造数据类型
在我们日常的开发过程中,我们经常定义使用常量;在Effective Java建议用枚举来替换常量的使用,提高我们代码的质量
创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum 类的子类(java.lang.Enum 是一个抽象类)。
枚举类型符合通用模式 Class Enum>,而 E 表示枚举类型的名称。
枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。
在项目开发中,推荐使用枚举常量代替接口常量或类常量。
[java]public enum Week {
MON, TUE, WED, THU, FRI, SAT, SUN;
}[/java]
这段代码实际上调用了7次 Enum(String name, int ordinal):
new Enum(“MON”,0);
new Enum(“TUE”,1);
new Enum(“WED”,2);
…….
用法一:常量
在JDK1.5 之前,我们定义常量都是: public static final…. 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
[java]
public enum Color {
RED, GREEN, BLANK, YELLOW
} [/java]
[java]Color color = Color.Red; //color -> Red;[/java]
用法二:switch
JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
[java] enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
[/java]
用法三:向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。
[java]public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
[/java]
用法四:覆盖枚举的方法
下面给出一个toString()方法覆盖的例子。
[java]public class Test {
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 覆盖方法
@Override
public String toString() {
return this.index + "_" + this.name;
}
}
public static void main(String[] args) {
System.out.println(Color.RED.toString());
}
}[/java]
用法五:实现接口
所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。
[java]public interface Behaviour {
void print();
String getInfo();
}
public enum Color implements Behaviour {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 接口方法
@Override
public String getInfo() {
return this.name;
}
// 接口方法
@Override
public void print() {
System.out.println(this.index + ":" + this.name);
}
}[/java]
用法六:使用接口组织枚举
[java]public interface Food {
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, LATTE, CAPPUCCINO
}
enum Dessert implements Food {
FRUIT, CAKE, GELATO
}
}[/java]
用法七:关于枚举集合的使用
java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型。
[java] /**
*
* 演示枚举类型的遍历
*/
private static void testTraversalEnum() {
Light[] allLight = Light.values();
for (Light aLight : allLight) {
System.out.println("当前灯name:" + aLight.name());
System.out.println("当前灯ordinal:" + aLight.ordinal());
System.out.println("当前灯:" + aLight);
}
}
/**
*
* 演示EnumMap的使用,EnumMap跟HashMap的使用差不多,只不过key要是枚举类型
*/
private static void testEnumMap() {
// 1.演示定义EnumMap对象,EnumMap对象的构造函数需要参数传入,默认是key的类的类型
EnumMap<Light, String> currEnumMap = new EnumMap<Light, String>(
Light.class);
currEnumMap.put(Light.RED, "红灯");
currEnumMap.put(Light.GREEN, "绿灯");
currEnumMap.put(Light.YELLOW, "黄灯");
// 2.遍历对象
for (Light aLight : Light.values()) {
System.out.println("[key=" + aLight.name() + ",value="
+ currEnumMap.get(aLight) + "]");
}
}
/**
*
* 演示EnumSet如何使用,EnumSet是一个抽象类,获取一个类型的枚举类型内容<BR/>
*
* 可以使用allOf方法
*/
private static void testEnumSet() {
EnumSet<Light> currEnumSet = EnumSet.allOf(Light.class);
for (Light aLightSetElement : currEnumSet) {
System.out.println("当前EnumSet中数据为:" + aLightSetElement);
}
}
}
[/java]
更详细原理参见:
转载请注明来源:Java枚举类型




























