语法(定义)
使用enum关键字创建枚举类型,隐含了所创建的类型都是 java.lang.Enum 类的子类(java.lang.Enum 是一个抽象类)。枚举类型符合通用模式 Class Enum<E extends Enum<E>>,而 E 表示枚举类型的名称。枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。
public enum EnumTest {
MON, TUE, WED, THU, FRI, SAT, SUN;
}
这段代码实际上调用了7次 Enum(String name, int ordinal):
new Enum<EnumTest>("MON",0);
new Enum<EnumTest>("TUE",1);
new Enum<EnumTest>("WED",2);
... ...
遍历、switch 等常用操作
for (EnumTest e : EnumTest.values()) {
System.out.println(e.toString());
}
EnumTest test = EnumTest.TUE;
switch (test) {
case MON:
System.out.println("星期一");
break;
case TUE:
System.out.println("星期二");
break;
// ... ...
default:
System.out.println(test);
break;
}
原理分析:
enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum<E>。EnumTest 经过反编译(javap com.test.EnumTest 命令)之后得到的内容如下:
public class com.test.EnumTest extends java.lang.Enum{
public static final com.test.EnumTest MON;
public static final com.test.EnumTest TUE;
public static final com.test.EnumTest WED;
public static final com.test.EnumTest THU;
public static final com.test.EnumTest FRI;
public static final com.test.EnumTest SAT;
public static final com.test.EnumTest SUN;
static {};
public int getValue();
public boolean isRest();
public static com.test.EnumTest[] values();
public static com.test.EnumTest valueOf(java.lang.String);
com.test.EnumTest(java.lang.String, int, int, com.test.EnumTest);
}
所以,实际上 enum 就是一个 class,只不过 java 编译器帮我们做了语法的解析和编译而已。另外,enum 不能使用 extends 关键字继承其他类,因为enum已经继承了 java.lang.Enum(java只支持单一继承)。
枚举类的属性:
枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰。
1)枚举类的使用 private final 修饰的属性应该在构造器中为其赋值。
2)若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数。
枚举类的主要方法:
values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值。
valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常。
getDeclaringClass():返回与此枚举常量的枚举类型相对应的 Class 对象。
name():返回此枚举常量的名称,在其枚举声明中对其进行声明。
ordinal():返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
toString():返回枚举常量的名称,它包含在声明中。
示例:
public class Seasons {
public static void main(String[] args) {
Season1 spring = Season1.SPRING;
System.out.println(spring);// 默认调用spring.toString()方法
System.out.println(spring.getSeasonName());
spring.show();
//使用values()方法可以返回整个枚举类的对象
Season1[] seasons = Season1.values();
for(Season1 s : seasons){
System.out.println(s);
}
//使用valueOf(String str)
String str = "SPRING";
Season1 season = Season1.valueOf(str);
System.out.println(season);
}
}
interface Info{
void show();
}
enum Season1 implements Info {
SPRING("SPRING", "春天") {
public void show() {
System.out.println("春暖花开");
}
},
SUMMER("SUMMER", "夏天") {
public void show() {
System.out.println("夏日炎炎");
}
},
AUTUMN("AUTUMN", "秋天") {
public void show() {
System.out.println("秋高气爽");
}
},
WINTER("WINTER", "冬天") {
public void show() {
System.out.println("白雪皑皑");
}
};
// 1.提供类的属性,并声明为private final
private final String seasonName;
private final String seasonDesc;
// 2.将声明为private final的属性在私有化的构造器中初始化
private Season1(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
// 3.通过公共的方法来调用私有属性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public String toString() {
return "Season1 [seasonName=" + seasonName + ", seasonDesc="
+ seasonDesc + "]";
}
public void show() {
System.out.println("这是一个季节!");
}
}