枚举类型简介
如果某个类只有有限的几个对象,比如季节类、行星类等,最好把这种类改为枚举类型。
自定义枚举类型
java在jdk1.5就增加了枚举类,但是了解早期自行定义枚举类的方法可以更好的理解枚举类型的定义。
枚举类的本质是只有有限的对象,需要3步来完成自定义枚举类的创建:
- 把有限的对象直接当做枚举类的公有的静态常量,公开给外界访问。
- 把构造器设置为私有,不让外界继续创建多余的对象。
- 只提供getter方法不提供setter方法,防止枚举对象的状态数据被随意修改。
举例:
public class Season {
// 有限的几个对象提前在类中创建,并且公开给外界访问
public static final Season SPRING = new Season("春天");
public static final Season SUMMER = new Season("夏天");
public static final Season AUTUMN = new Season("秋天");
public static final Season WINTER = new Season("冬天");
// 枚举对象的状态数据没有setter方法,不让外界更改
private final String name;
// 私有的构造方法防止外界创建多余的对象
private Season(String name) {
this.name = name;
}
// 重写toString方法
public String toString() {
return name;
}
}
enum关键字
jdk1.5新增了一个enum关键字,它相当于一个特殊的类,专门用于定义枚举类型。
枚举类和普通类的异同
相同点:
- 枚举类也可以有自己的成员变量、方法、构造器。
- 枚举类也可以实现一个或多个接口。
- 枚举类和文件也有类似的规则,public枚举类一个文件只能有一个,而且文件名必须和public枚举类同名。
不同点:
- 枚举类默认继承java.lang.Enum类,而Enum类实现类Serializable, Comparable两个接口。
- 枚举类的构造器默认为private,写不写访问修饰符都一样(目的是防止外界调用构造器随意创建对象)。
- 非抽象的枚举类默认被final修饰,不能拥有子类(因为enum类如果为父类,子类无法调用其私有的构造器)。
- 枚举类的内部第一行必须先列出所有实例,这些实例就是这个枚举类所有的对象。它们都默认带有public staic final修饰,不需要显式添加。
- 枚举类自带一个values()方法,会返回枚举类所有对象组成的一个数组。
举例:
public enum Season {
// 第一行必须列出该Season这个枚举类所有的对象
// 比如SPRING("春天")本质其实是public static final Season SPRING = new Season("春天"); enum类的语法省略了多余的部分
SPRING("春天"), SUMMER("夏天"), AUTUMN("秋天"), WINDER("冬天");
private final String name;
// Season枚举类的构造器默认是私有的,不需要写private访问修饰符
Season(String name) {
this.name =name;
}
public String getName() {
return name;
}
}
使用枚举类
使用枚举类只需要直接访问枚举类的几个对象,语法为:类名.实例名
比如:Season.SPRING
得到枚举类的对象后,可以正常访问枚举类的所有方法,还可以与switch语句配合使用。
枚举类与switch
switch语句的switch(表达式)中的表达式里可以是枚举类型的变量,case语句后可以写不同的枚举类型的对象,根据枚举变量的值进行对应的匹配。
在switch语句中,由于表达式已经确定了枚举类的类型,所有case部分在写枚举对象时,可以省略类型的前缀。
举例:
public void judge(Season season) {
switch(season) {
case SPRING:
System.out.println("春天");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINDER:
System.out.println("冬天");
break;
default:
System.out.println("无法匹配");
break;
}
}
Enum类的常用方法
所有的枚举类都继承自Enum类,Enum类有一些常用方法可供使用:
- public String toString(); Enum类重写了toString方法,用于返回枚举常量的名字。 它和name()方法的功能差不多,但是更推荐使用这个重写的toString方法。
- public final int ordinal(); 返回枚举常量的序数,这个序数从零开始,表示枚举常量定义的顺序。
- public final int compareTo(E o); 比较两个枚举对象的定义顺序,返回值为两个枚举对象序列值的差值。
- public static <T extends Enum> T valueOf(Class enumType, String name); 第一个参数来制定要返回的枚举类型,第二个参数是一个字符串,会把该字符串解析为对应的枚举常量
枚举类的成员变量
为了保证良好的封装,枚举类的成员变量最好设置为private final类型,同时通过私有的构造器来为其赋值。这样,在每个枚举常量被创建出来后,它对应的状态数据就已经固定了。枚举类之后只需要提供getter方法让外界访问这些状态数据。
举例:
public enum Gender {
MALE("男"), FEMALE("女");
// 状态数据设置为private final,保证良好的封装
private final String name;
// 通过私有的构造器一开始就设定好每个枚举常量的值
Gender(String name){
this.name = name;
}
// 提供公开的getter方法
public String getName() {
return name;
}
}
values方法
通过javap反编译枚举的类文件,可以发现枚举类自带一个values方法
public static enumType[] values(); values方法会返回该枚举类型所有的枚举常量,组成一个数组。