一、枚举的定义:
枚举类型是一种特殊数据类型,能够为一个变量定义一组预定义的常量。变量必须等于为其预定义的值之一。
枚举都是被关键字enum修饰的类型。
可以把枚举看做一个特殊的类,把枚举的常量看作是枚举这个特殊类的实例。
例:
enum Week{MON, TUE, WED, THU, FRI, SAT, SUN}
这里就是定义了一个名为week的枚举类型,如果需要访问枚举类型中的常量时我们用“枚举类型名.要引用的常量”去访问。
二、枚举的遍历:
1、foreach以及枚举自带的value方法遍历
for(Week w: Week.values()){
System.out.println(w);
}
枚举自带的values方法可以将枚举转换为数组类型。这样就可以用适用于集合的foreach便利方法。
2.for循环遍历
for(int i=0; i<Week.values().length; i++){
System.out.println(Week.values()[i]);
}
“Week.values()[i]”的原因是values将枚举类Week转化为一个数组,要按照下标才能输出数组元素。
枚举的switch case运用:
Week w = Week.FRI;//枚举类型名可以直接调用成员
switch(w){
case FRI:
System.out.println("FRIDAY");
break;
......
}
Java中的枚举都继承自一个java.lang.Enum类,Java中的枚举类型里面的每一个枚举成员也都是public static final,使用时直接通过枚举名调用成员。
二、枚举的常用方法
1、values():将枚举转化为数组形式。
2、valueOf :将字符串转为枚举类型的成员。
例:在一个名为“Color”的枚举里,有成员“Blue”,此时如果我们对“Blue”字符串调用valueOf那么会返回“Blue”
3、compareTo:用于比较两个枚举,0表示相同,1表示前面比后面更靠前1个,-1表示后面更靠前一个。
4、ordinal返回成员在枚举类里边的索引,注意枚举里边的索引是从0开始的
例:
enum Week{MON, TUE, WED, THU, FRI, SAT, SUN};//定义枚举Week
......
for(int i=0; i<Week.values().length; i++){
System.out.println("枚举成员: "+Week.values()[i]);
}
System.out.println(Week.valueOf("MON"));//输出MON
System.out.println(Week.valueOf("MON").compareTo(Week.FRI));
//输出-4,因为MON比FRI靠前4个。
System.out.println(Week.valueOf("MON").compareTo(Week.MON));
//输出0,因为相同
System.out.println(Week.FRI.ordinal());//输出4,因为FRI的索引是4.
三、在枚举中添加方法:
在枚举中添加方法时要注意:如果打算在enum类中定义方法,务必在声明完枚举实例后使用分号分开,倘若在枚举实例前定义任何方法,编译器都将会报错,无法编译通过。
注意:枚举的构造函数是默认private的!枚举的构造函数只有在枚举里每个枚举成员初始化的时候才会调用。有几个成员初始化就调用构造函数几次。
例:
enum Week{
MON("monday"), TUE("tuesday"), WED("wednesday"), THU("thuraday"), FRI("friday"), SAT("saturday"), SUN("sunday");
Week(String name){
//枚举中的构造函数默认为私有方法。
System.out.println("initialize");
this.name = name;
}
switch (i) {
case 0:
System.out.println(Week.MON);
break;
case 1:
System.out.println(Week.TUE);
break;
case 2:
System.out.println(Week.WED);
break;
case 3:
System.out.println(Week.THU);
break;
case 4:
System.out.println(Week.FRI);
break;
case 5:
System.out.println(Week.SAT);
break;
case 6:
System.out.println(Week.SUN);
break;
default:
System.out.println("wrong number");
}
}
四、枚举中重写方法:
注意,虽然枚举里边的每一个枚举成员都是public static final的,但是枚举之中其他所有添加的成员变量或者重写的成员方法都要默认是private的,因为枚举只允许外部程序访问到其枚举成员!
例:重写枚举中的toString方法,使其改为输出枚举成员的name。
enum Week{
MON("monday"), TUE("tuesday"), WED("wednesday"), THU("thuraday"), FRI("friday"), SAT("saturday"), SUN("sunday");
private String name;
//枚举中除了枚举成员之外的所有属性以及成员方法都默认为私有的
Week(String name){
System.out.println("initialize");
this.name = name;
}
@Override
public String toString() {
return this.name + " ";
}
}
五、枚举实现单例模式:
实现原理:因为枚举成员只会被初始化一次,所以把当前的实例作为一个枚举成员存在,然后通过一个getInstance的方法得到这个成员。
例:
class EnumSingleton{
private enum Singleton{
INSTANCE;
//INSTANCE是枚举中的唯一的枚举成员,所以是public static final的
private EnumSingleton singleton;
//因为最后要返回EnumSingleton类的实例化对象
//故把EnumSingleton类的对象定义为枚举成员的一个属性。
Singleton(){
singleton = new EnumSingleton();
}//只有一个枚举成员,即构造函数只会被调用一次
}
public static EnumSingleton getInstance(){
return Singleton.INSTANCE.singleton;
}
}
通过枚举实现单例模式,在类中建立一个只有一个枚举成员的枚举,把类的实例化引用写为这个唯一的枚举成员的属性,因为枚举的构造函数只会在枚举成员初始化时才会调用,而只有一个枚举成员那么构造函数也就只会调用一次,那么也就只会实例化一次枚举成员,这样作为枚举成员属性的类的实例化也就只会实例化一次。