Java枚举有如下特点:
- 枚举类省略了private类型的构造函数,且构造函数只能为私有;
- 枚举的域(field)实质就是相应的枚举类的一个实例对象;
- 当访问枚举的实例(域)时才会执行构造方法实例化,例如下面的DAY实例只有被访问时才会被创建;
- 枚举的实例(域)都被static final修饰,保证了只能被实例化一次;
- 编译器会自动为枚举继承java.lang.Enum的类,所以代码中枚举只能实现接口而不能再继承其他类;
枚举原理
下面看一个简单的枚举类:
package com.faith.net;
/**
* 日期类型
*/
public enum DateType {
DAY;
}
上面的代码在编译后实际等同于:
public class DateType extends Enum {
public static final DateType DAY;
private DateType () {}
}
可以把DateType看做一个类,而Day是DateType的一个实例。它的构造方法则是私有的。
枚举添加静态变量/方法和成员变量/方法
枚举中也可以添加静态变量、静态方法和成员变量、成员方法:
public enum DateType {
DAY;
static int value;
public static int getValue() {
return value;
}
String name;
public String getName() {
return name;
}
}
我们把DateType看做一个类,静态变量和静态方法和普通类调用方式一样:
DateType.value
DateType.getValue()
成员变量和成员方法是每个类的实例才能调用的方法。而枚举类的实例就是它的域。所以调用枚举的成员变量和方法,通过如下方式:
DateType.DAY.name
DateType.DAY.getName()
重写枚举成员方法
枚举的每个实例(域)还可以重写枚举中的成员方法,类似于多态,如下:
public enum DateType {
DAY {
public Integer getValue() {
return 0;
}
};
static Integer value = 1;
public static Integer getValue() {
return value;
}
String name;
public String getName() {
return name;
}
}
DAY中重写了getValue方法,重写前DateType.DAY.getValue()值为1,重写后则调用DAY中自己定制的getValue方法,结果为0。
枚举添加抽象方法
还可以在枚举中添加抽象方法,强制所有实例(域)都实现各自的处理逻辑:
public enum DateType {
DAY {
@Override
public String getText() {
return null;
}
},
WEEK {
@Override
public String getText() {
return null;
}
};
public abstract String getText(); // 抽象方法,强制所有实例实现
}
枚举实现接口
强制实例必须实现方法还可以通过实现接口:
public interface NameEnum {
String getName();
}
public enum DateType implements NameEnum {
DAY {
@Override
public String getName() {
return null;
}
},
Week {
@Override
public String getName() {
return null;
}
};
}
带参构造
枚举使用带参构造函数:
package com.faith.net;
import java.util.HashMap;
import java.util.Map;
/**
* 日期类型
*
* @author hugende
*/
public enum DateType {
DAY("sdfsdf", 0) {
@Override
public String getText() {
return null;
}
},
WEEK("sdf", 1) {
@Override
public String getText() {
return null;
}
};
public abstract String getText();
String name;
Integer age;
DateType(String name, Integer age) {
this.name = "s";
this.age = age;
}
}
访问方式如下:
DateType.DAY.name // 0
DateType.WEEK.name // 1
遍历枚举
枚举提供了values方法:
public class EnumTest {
public static void main(String[] args) {
DateType[] values = DateType.values();
for (DateType dateType : values) {
System.out.println(dateType.age);
}
}
}
枚举的父类
Java强制枚举实现了Enum类,这个类的声明如下:
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable
可见其实现了Comparable、Serializable,支持了比较与序列化传输。