语法(定义)
创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum 类的子类(java.lang.Enum 是一个抽象类)。枚举类型符合通用模式 Class Enum<E extends Enum<E>>
,而 E
表示枚举类型的名称。枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal)
构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。
public enum Day {
MON, TUE, WED, THU, FRI, SAT, SUN;
public static void main(String[] args) {
for(Day day:Day.values()){
System.out.println( day.toString() );
}
Day mon= Day.MON;
switch (mon) {
case MON:
System.out.println( "MON" );
break;
case TUE:
System.out.println( "TUE" );
break;
default:
break;
}
//compareTo(E o ) 比较此枚举与指定对象的顺序
switch (mon.compareTo(Day.TUE)) {
case -1:
System.out.println("MON 在 TUE 之前");
break;
case 1:
System.out.println("MON 在 TUE 之后");
break;
default:
System.out.println("MON 与 TUE 在同一位置");
break;
}
//Class<E> getDeclaringClass() 返回与此枚举常量的枚举类型相对应的 Class 对象(全限定名)。
System.out.println("getDeclaringClass(): " + mon.getDeclaringClass().getName());
//String name() 返回此枚举常量的名称,在其枚举声明中对其进行声明。
System.out.println("name(): " + mon.name());
//String toString() 返回枚举常量的名称
System.out.println("toString(): " + mon.toString());
//int ordinal() 返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)
System.out.println("ordinal(): " + mon.ordinal());
//static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) 返回带指定名称的指定枚举类型的枚举常量。
System.out.println( Day.valueOf( Day.class, "MON" ) );
// EnumSet的使用
EnumSet<Day> weekSet = EnumSet.allOf(Day.class);
for (Day day : weekSet) {
System.out.println(day);
}
// EnumMap的使用
EnumMap<Day, String> weekMap = new EnumMap<Day, String>(Day.class);
weekMap.put(Day.MON, "星期一");
weekMap.put(Day.TUE, "星期二");
for (Iterator<Entry<Day, String>> iter = weekMap.entrySet().iterator(); iter.hasNext();) {
Entry<Day, String> entry = iter.next();
System.out.println(entry.getKey().name() + ":" + entry.getValue());
}
}
}
MON, TUE, WED, THU, FRI, SAT, SUN; 这段代码实际上调用了7次 Enum(String name, int ordinal):
new
Enum<Day>(
"MON"
,
0
);
new
Enum<Day>(
"TUE"
,
1
);
new
Enum<Day>(
"WED"
,
2
);
... ...
|
原理分析
enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum<E>。Day经过反编译之后得到的内容如下:
public
class
com.test.
Day
extends
java.lang.Enum{
public
static
final
com.test.DayMON;
public
static
final
com.test.DayTUE;
public
static
final
com.test.DayWED;
public
static
final
com.test.DayTHU;
public
static
final
com.test.DayFRI;
public
static
final
com.test.DaySAT;
public
static
final
com.test.DaySUN;
static
{};
public
int
getValue();
public
boolean
isRest();
public
static
com.test.Day[] values();
public
static
com.test.DayvalueOf(java.lang.String);
com.test.Day(java.lang.String,
int
,
int
, com.test.Day);
}
|
所以,实际上 enum 就是一个 class,只不过 java 编译器帮我们做了语法的解析和编译而已。
总结
可以把 enum 看成是一个普通的 class,它们都可以定义一些属性和方法,不同之处是:enum 不能使用 extends 关键字继承其他类,因为 enum 已经继承了 java.lang.Enum(java是单一继承).
LoginLimitType枚举类就是class,而且是一个不可以被继承的final类。其枚举值(NO,YES...)都是Color类型的类静态常量
(1) 构造器只是在构造枚举值的时候被调用。构造器只能私有private,这样可以保证外部代码无法新构造枚举类的实例
(2) NO("0", "不允许") 其实就是调用了一个构造函数,枚举类中构造函数须给出
public enum LoginLimitType {
NO("0", "不允许"),YES("1", "允许");
private String code;
private String descs;
LoginLimitType(String code, String descs) {
this.code = code;
this.descs = descs;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescs() {
return descs;
}
public void setDescs(String descs) {
this.descs = descs;
}
public static String getDesc(Integer value){
for (LoginLimitType lt : LoginLimitType.values()) {
if(lt.code.equals( value)){
return lt.descs;
}
}
return null;
}
}