Java枚举类笔记,摘自《疯狂Java讲义》

枚举类

在早期代码中,可能会直接使用简单的静态常量表示枚举,例如如下代码:

1
2
3
4
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_FALL = 3;
public static final int SEASON_WINTER = 4;

但是这种方式定义会存在如下问题:

  • 类型不安全:可能存在SEASON_SPRING + SEASON_FALL。
  • 没有命名空间:当需要使用季节时,必须在SPRING钱使用SEASON_前缀,否则程序可能与其他类中的静态常量混淆。
  • 打印输出的意义不明确:当输出某个季节时,实际的输出值时数字。

JDK1.5 之后新增了enum关键字,用来定义枚举类。枚举类是一种特殊类,有自己的成员变量、方法,可以实现一个或者多个接口,可以定义自己的构造器。一个Java源文件中最多只能定一个public访问权限的枚举类,且该Java源文件必须和该枚举类的类名相同。和普通类区别如下:

  • 使用enum定义的默认枚举类默认继承了java.lang.Enum类。其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。
  • 使用enum定义、非抽象的枚举类默认会使用final修饰,因此不能派生子类。
  • 枚举类的构造器只能使用private访问控制符。
  • 枚举类所有的实例必须在枚举类的第一行显示列出,否则这个枚举类永远都不能产生实例。

Java枚举类型基本思想:通过公有的静态final域为每个枚举常量到处实例的类。因为没有可以访问的构造器,枚举类型是真正的final。

1. 枚举类的成员变量、方法和构造器

枚举类也是一种比较特殊的类。示例如下:

1
2
3
4
5
6
7
8
9
10
public enum Gender{
MALE("男"),FEMALE("女");
private final String name;
private Gender(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}

上面代码可以看出,枚举类中列出枚举值时,实际上就是调用构造器创建枚举类对象,只是这里不是使用new关键字,也无需显式调用构造器。

上面MALE("男"),FEMALE("女")等同于

1
2
public static void final Gender MALE = new Gender("男");
public static void final Gender FEMALE = new Gender("女");

2. 实现接口的枚举类

接口:

1
2
3
public interface GenderDesc{
void info();
}

实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public enum Gender{
MALE("男"){
public void info(){
System.out.println("men");
}
},FEMALE("女"){
public void info(){
System.out.println("women");
}
};
private final String name;
private Gender(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}

注:并非所有的枚举类都使用final修饰,非抽象的枚举类才默认使用final修饰。对于一个抽象的枚举类,系统默认使用abstract修饰,而不是final。

3. 包含抽象方法的抽象类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public enum Operation{

PLUS{
public double eval(double x, double y){
return x+y;
}
},
MINUS{
public double eval(double x, double y){
return x-y;
}
},
TIMES{
public double eval(double x, double y){
return x*y;
}
},
DIVIDE{
public double eval(double x, double y){
return x/y;
}
};

public abstract double eval(double x, double y);
}

引用

疯狂Java讲义