枚举 enum
1. 枚举概述.
enum 的全称enumeration,是指将变量的值一一列出来。变量的值只限于列举出来的值的范围内。举例:一周只有7天,一年只有12个月。
如果枚举不添加任何方法,枚举值默认为从0开始的有序数值
枚举的好处: 可以将常量组织起来,统一进行管理。
枚举的典型应用场景: 错误码、状态机等。
2. 回想单例设计模式:单例类是一个类只有一个实例。
那么多例类就是一个类有多个实例,但不是无限个数的实例,而是有限个数的实例,这才能是枚举类。
3. 自定义枚举类
public class Week {
//单例模式的第三种方法
public static final Week MON = new Week();
public static final Week TUE = new Week();
public static final Week WED = new Week();
//私有构造
private Week(){}
}
class Week2 {
//单例模式的第三种方法
public static final Week2 MON = new Week2("星期一");
public static final Week2 TUE = new Week2("星期二");
public static final Week2 WED = new Week2("星期三");
//定义属性
private String name;
//私有构造
private Week2(String name){
this.name = name;
}
//提供访问的方法
public String getName() {
return name;
}
}
abstract class Week3 {
//单例模式的第三种方法
public static final Week3 MON = new Week3("星期一"){
@Override
void fun() {
System.out.println("星期一");
}
};
public static final Week3 TUE = new Week3("星期二"){
@Override
void fun() {
System.out.println("星期二");
}
};
public static final Week3 WED = new Week3("星期三"){
@Override
void fun() {
System.out.println("星期三");
}
};
//定义属性
private String name;
//私有构造
private Week3(String name){
this.name = name;
}
//提供访问的方法
public String getName() {
return name;
}
//定义抽象的方法
abstract void fun();
}
测试
public class WeekEnmu_Test {
public static void main(String[] args) {
demo1();
//demo2();
//demo3();
}
private static void demo3() {
Week3 mon = Week3.MON;
mon.fun();
}
private static void demo2() {
Week2 mon = Week2.MON;
System.out.println(mon.getName());
}
private static void demo1() {
Week mon = Week.MON;
Week tue = Week.MON;
Week wed = Week.MON;
System.out.println(mon);
}
}
4. 通过enum实现枚举类
public enum Week {
MON("星期一"),TUE("星期二"),WED("星期三");
private String name;
Week(String name){
this.name = name;
}
public String getName(){
return name;
}
}
public enum Week2 {
MON("星期一"){
@Override
void show() {
System.out.println("星期一");
}
},TUE("星期二"){
@Override
void show() {
System.out.println("星期二");
}
},WED("星期三"){
@Override
void show() {
System.out.println("星期三");
}
};
private String name;
Week2(String name){
this.name = name;
}
public String getName(){
return name;
}
abstract void show();
}
测试
public class WeekTest {
public static void main(String[] args) {
//test1();
//test2();
Week2 wed = Week2.WED;
wed.show();
}
private static void test2() {
Week tue = Week.TUE;
System.out.println(tue.getName());
}
private static void test1() {
Week mon = Week.MON;
System.out.println(mon);
}
}
5. 注意事项
- 定义枚举类需要用到关键字enum.
- 所有枚举类都是Enum的子类,所以枚举类除了不能继承,基本上就是一个常规类.
- 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号,在该枚举类没有其它东西的时候是可以省略的.建议不要省略.
- 枚举类可以有构造器,但必须是私有的,它默认也是私有的.
- 枚举类也可以有抽象方法,但是枚举项必须重写该方法.
- 我们经常使用switch语句来写状态机。JDK7以后,switch已经支持
int
、char
、String
、enum
类型的参数。这几种类型的参数比较起来,使用枚举的switch代码更具有可读性。
public class Demo {
public static void main(String[] args) {
String trafficInstruct = getTrafficInstruct(Signal.GREEN);
System.out.println(trafficInstruct);
}
public static String getTrafficInstruct(Signal signal) {
String instruct = "信号灯故障";
switch (signal) {
case RED:
instruct = "红灯停";
break;
case YELLOW:
instruct = "黄灯请注意";
break;
case GREEN:
instruct = "绿灯行";
break;
default:
break;
}
return instruct;
}
}
6. 常见方法
int compareTo(E e):比较两个枚举常量谁大谁小,其实比较的就是枚举常量在枚举类中声明的顺序,例如FRONT的下标为0,BEHIND下 标为1,那么FRONT小于BEHIND;
boolean equals(Object o):比较两个枚举常量是否相等;
int hashCode():返回枚举常量的hashCode;
String name():返回枚举常量的名字;
int ordinal():返回枚举常量在枚举类中声明的序号,第一个枚举常量序号为0;
String toString():把枚举常量转换成字符;
static T valueOf(Class enumType, String name):把字符串转换成枚举常量;
values(),每个枚举类都具有该方法,用来遍历枚举类的所有枚举值非常方便;