Java枚举用法详解
在 Java 中,枚举(Enum)是一种有确定取值区间的数据类型,它本质上是一种类,具有简洁、安全、方便等特点。可以这样理解,枚举的值被约束到一个特定的范围,只能取这个范围以内的值。
在了解枚举的具体概念之前,我们先来思考一个问题:为什么要有枚举呢?
我们在描述对象的一些属性特征时,可选择的值是有一个特定范围的,即该属性的值不能随便定义。比如:
出于对数据的安全性考虑,类似这种有特定取值范围的数据我们就可以使用枚举来描述,这就是使用枚举的意义所在。
枚举指由一组常量组成的类型,指定了一个取值区间,我们只能从这个区间中取值。再来看枚举的定义,在没有枚举之前,我们需要定义一个类来描述周一到周日,可以通过定义静态常量的方式来完成,例如:
这种方式是可以完成需求的,但是编写起来会比较麻烦,用 int 类型的数据来描述周几也不是很直观,如果使用枚举类型就会方便很多,例如:
拿上面这个例子来说,Java 在编译期会帮我们生成一个 Week 类,并且继承自 java.lang.Enum,被 final 修饰,表示该类不可被继承。同时还生成了 7 个 Week 的实例对象分别对应枚举中定义的 7 个日期,因为枚举的静态常量直接对应其实例化对象,所以对于枚举的使用如下面的代码所示:
编译期生成的类如下:
静态代码块中通过私有构造函数对 7 个静态常量以及静态数组常量赋值,所以上面程序中打印的枚举值其实就是创建该对象时传入的 String 类型参数,如"MONDAY"。
同时该类还为我们提供了两个静态方法 values() 和 valueOf(String s),values() 方法可以返回该枚举的所有常量,vauleOf(String s) 可以通过字符串s创建对应的枚举对象,具体操作如下:
在了解枚举的具体概念之前,我们先来思考一个问题:为什么要有枚举呢?
我们在描述对象的一些属性特征时,可选择的值是有一个特定范围的,即该属性的值不能随便定义。比如:
- 性别就只能选择男和女;
- 一周只有周一到周日这 7 个选择,不可能出现星期八;
- 一年只有春、夏、秋、冬4个季节。
出于对数据的安全性考虑,类似这种有特定取值范围的数据我们就可以使用枚举来描述,这就是使用枚举的意义所在。
枚举指由一组常量组成的类型,指定了一个取值区间,我们只能从这个区间中取值。再来看枚举的定义,在没有枚举之前,我们需要定义一个类来描述周一到周日,可以通过定义静态常量的方式来完成,例如:
public class Week { public static final int MONDAY = 0; public static final int TUESDAY = 1; public static final int WEDNESDAY = 2; public static final int THURSDAY = 3; public static final int FRIDAY = 4; public static final int SATURDAY = 5; public static final int SUNDAY = 6; }
这种方式是可以完成需求的,但是编写起来会比较麻烦,用 int 类型的数据来描述周几也不是很直观,如果使用枚举类型就会方便很多,例如:
public enum Week { MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY; }枚举的定义与类很相似,使用 enum 关键字来描述,基本语法如下:
public enum 枚举名{ 值1,值2,值3... }注意,枚举中的常量使用逗号进行分割,看到这里有的读者可能会有疑惑,枚举中的常量值是什么呢?枚举中的每一个常量都对应的是一个枚举实例,只不过表示的含义不同。
拿上面这个例子来说,Java 在编译期会帮我们生成一个 Week 类,并且继承自 java.lang.Enum,被 final 修饰,表示该类不可被继承。同时还生成了 7 个 Week 的实例对象分别对应枚举中定义的 7 个日期,因为枚举的静态常量直接对应其实例化对象,所以对于枚举的使用如下面的代码所示:
public class Test { public static void main(String[] args) { Week week = Week.MONDAY; System.out.println(week); } }运行结果为:
MONDAY
编译期生成的类如下:
final class Week extends Enum { public static final Week MONDAY; public static final Week TUESDAY; public static final Week WEDNESDAY; public static final Week THURSDAY; public static final Week FRIDAY; public static final Week SATURDAY; public static final Week SUNDAY; private static final Week $VALUES[]; static { MONDAY = new Week("MONDAY", 0); TUESDAY = new Week("TUESDAY", 1); WEDNESDAY = new Week("WEDNESDAY", 2); THURSDAY = new Week("THURSDAY", 3); FRIDAY = new Week("FRIDAY", 4); SATURDAY = new Week("SATURDAY", 5); SUNDAY = new Week("SUNDAY", 6); $VALUES = (new Week[] { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }); } public static Week[] values() { return (Week[])$VALUES.clone(); } public static Week valueOf(String s) { return (Week)Enum.valueOf(com/southwind/Week, s); } private Week(String s, int i) { super(s, i); } }解读一下这个类,首先定义了 7 个 Week 类型的静态常量和一个 Week 类型的静态数组常量。同时定义了一个私有的构造函数,String 类型的参数即当前枚举对象的值,int 类型的参数为它的下标。
静态代码块中通过私有构造函数对 7 个静态常量以及静态数组常量赋值,所以上面程序中打印的枚举值其实就是创建该对象时传入的 String 类型参数,如"MONDAY"。
同时该类还为我们提供了两个静态方法 values() 和 valueOf(String s),values() 方法可以返回该枚举的所有常量,vauleOf(String s) 可以通过字符串s创建对应的枚举对象,具体操作如下:
public class Test { public static void main(String[] args) { Week[] weeks = Week.values(); for(Week week:weeks) { System.out.println(week); } System.out.println("----------"); Week week = Week.valueOf("MONDAY"); System.out.println(week); } }运行结果为:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
----------
MONDAY