枚举类型可以取代以往常量的定义方式,即将常量封装在类或接口中。此外,枚举类型还提供了安全检查功能。枚举类型本质上还是以类的形式存在。
1.枚举声明
声明枚举时必须使用 enum 关键字,然后定义枚举的名称、可访问性、基础类型和成员等,可以实现接口但不能继承类,因为已经继承了Enum类(Java单继承)。枚举声明的语法如下:
修饰符(public、private、internal) enum 自定义名称{
枚举成员1(多个自定义属性,必须和构造函数的参数相同),
枚举成员2(...),
枚举成员3(...),
.......
枚举成员n(...);
}
任意两个枚举成员不能具有相同的名称,且它的常数值必须在该枚举的基础类型的范围之内,多个枚举成员之间使用逗号(,)分隔,枚举成员一般为全大写字母,在最后加分号。如果没有显式地声明基础类型的枚举,那么意味着它所对应的基础类型是 int。
同时我们可以在枚举中添加自定义的变量(final修饰的)、方法(可以没有,但为了获取值一般有get方法)、构造函数(必须声明为私有(private)),但一定得保证枚举成员括号里的参数和构造函数的参数个数和类型对应,否则编译报错。在枚举成员赋值时要么全赋值,要么全部赋值,只有一部分赋值而另一部分不赋值时会发生编译错误。
public enum Enum1 {
MON(1,"星期一","工作"), //需要和构造函数的个数和类型一致
TUE(2,"星期二","工作"),
WES(3,"星期三","工作"),
THU(4,"星期四","工作"),
FIR(5,"星期五","工作"),
STU(6,"星期六","休息"),
SUN(7,"星期天","休息");
private final int o; //变量用final修饰,不可改变
private final String s;
private final String doSomething;
Enum1(int o,String s,String doSomething){ //默认为private
this.o=o;
this.s=s;
this.doSomething=doSomething;
}
public int getO() { //自定义方法,可以随便写逻辑
return o;
}
public String getS() {
return s;
}
public String getDoSomething() {
return doSomething;
}
}
2.枚举的实现原理
在使用关键字enum创建枚举类型并编译后,编译器会为我们生成一个相关的类,这个类继承了Java API中的java.lang.Enum类,也就是说通过关键字enum创建枚举类型在编译后事实上也是一个类类型而且该类继承自java.lang.Enum类。在编译enum枚举时,编译器会生成两个静态方法valueOf()和values()方法,其中的valueOf()方法在Enum父类中存在,而values()方法只存在于enum的类中。
使用关键字enum定义的枚举类型,在编译期后,也将转换成为一个实实在在的类,而在该类中,会存在每个在枚举类型中定义好变量的对应实例对象,如枚举类型MON对应了public static final Enum1 MON;初始值会在static{}代码块中完成。
3.枚举类型的方法
一般常用的枚举类型方法,主要是Enum类中的方法,但是也有编译生成的values()方法,这是enum编译后独有的,Enum中并无此方法。
- values方法:以数组形式返回枚举类型的所有成员,不能由Enum调用。
Enum1[] enum1 = Enum1.values();
for (Enum1 enum11:enum1){
System.out.println(enum11.getS()+enum11.getDoSomething());
}
- valueOf方法:将普通字符串转换为枚举实例。
Enum1 ens = Enum1.valueOf("MON");
System.out.println(ens.getS());
- compareTo方法:由于Enum类实现了Comparable接口并实现了compateTo方法,所以枚举可以使用此方法,主要比较两个枚举成员在定义时的顺序。
Enum1 enum2 = Enum1.valueOf("MON"); //第一个定义,序号为0
Enum1 enum3 = Enum1.valueOf("THU"); //第四个定义,序号为3
System.out.println(enum2.compareTo(enum3)); //enum2.compareTo(enum3) -> 0-3=-3,最终结果为-3
- ordinal方法:获取枚举成员的索引位置,默认第一个从0开始。
Enum1 enum2 = Enum1.valueOf("MON");
System.out.println(enum2.ordinal()); //MON是第一个,序号为0
Enum1 enum3 = Enum1.valueOf("THU");
System.out.println(enum3.ordinal()); //THU是第四个,序号为3
Class类中操作枚举的方法有getEnumConstants()、isEnum()方法。
- getEnumConstants方法:返回该枚举类型的所有元素,如果Class对象不是枚举类型,则返回null。
Enum e = Enum1.MON; //向上转型,但是由于Enum中没有values()方法,调用此方法报错,可以利用反射解决
Class<Enum> c = e.getDeclaringClass();
Enum[] enums = c.getEnumConstants();
for (Enum en:enums){
System.out.println(en.name());
}
- isEnum方法:当且仅当该类声明为源代码中的枚举时返回 true
System.out.println(Enum1.class.isEnum()); //true
4.枚举类型优点
枚举类型声明提供了一种用户友好的变量定义方法,枚举了某种数据类型所有可能出现的值。总结枚举类型,它具有以下特点:
- 类型安全。
- 紧凑有效的数据定义。
- 可以和程序其他部分完美交互。
- 运行效率高。
本人小白一个,如果有什么问题还请您在评论区留言!感谢