抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

摘要:本文学习了枚举的概念和使用。

环境

Windows 10 企业版 LTSC 21H2
Java 1.8

1 简介

从JDK1.5开始,增加了枚举(Enumeration)类型,允许定义一组固定的常量值。

使用枚举类可以弥补常量的以下几个缺陷:

  • 类型不安全。如果需要传入int类型的性别,可以传入int类型的任意值。但如果需要传入枚举类型的性别,就只能传入枚举类中包含的对象。
  • 没有命名空间。枚举类可以使用Sex作为前缀,这样其他开发者会知道这个枚举代表性别。

2 说明

枚举类默认继承Enum类,而不是Object类,因此枚举类不能显示继承其他父类。

使用enum定义的非抽象的枚举类默认使用final修饰,不能被继承。使用enum定义的抽象的枚举类默认使用abstract修饰,可以被继承。

枚举类的构造器默认并且只能使用private访问控制符,如果强制指定其他的访问控制符会报错。

枚举类的所有实例必须在枚举类的第一行显示列出,否则这个枚举类永远都不可能产生实例。列出的这些实例,系统会自动给它们加上public static final修饰。枚举类的实例以逗号分隔,分号结束,这些列出的枚举值代表了该枚举类的所有可能的实例。

3 使用

当switch控制表达式使用枚举类型时,后面case表达式中的值可以直接使用枚举值的名字。

创建枚举类:

java
1
2
3
public enum SexEnum {
FEMALE, MALE;
}

使用枚举类:

java
1
2
3
4
5
6
7
8
9
10
11
12
public void test(SexEnum sex) {
switch (sex) {
case FEMALE:
System.out.println("性别女");
break;
case MALE:
System.out.println("性别男");
break;
default:
break;
}
}

获取枚举类所有实例:

java
1
2
3
4
5
6
public void test() {
SexEnum[] values = SexEnum.values();
for (SexEnum sex : values) {
System.out.println(sex);
}
}

4 成员

枚举类是一种特殊的类,它一样可以有自己的成员变量、方法,可以有自己的构造器,也可以实现一个或多个接口,但不能继承其他的类。

枚举类的每个实例的成员变量的值是不能改变的,而且不需要使用修饰符修饰。

所有成员变量都使用final修饰,必须使用下面三种方法为成员变量指定初始值:

  • 在构造器里为这些成员变量指定初始值。
  • 在定义成员变量时指定默认值。
  • 在初始化块中指定初始值。

实际上,后面两种方式并不常用。所以,应该为枚举类显示定义带参数的构造器,列举枚举值时就传入对应的参数。

示例:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
public enum SexEnum {
FEMALE(0), MALE(1);

int sex;

private SexEnum(int sex) {
this.sex = sex;
}

public void showSex() {
System.out.println(sex);
}
}

在第一行列出所有枚举值时,实际上就是调用了构造器创建枚举类对象,只是这里不需要使用new关键字,也无需显示调用构造器罢了。

如果在定义SexEnum时,没有传入参数,甚至没有使用括号,那么使用的就是SexEnum里默认的无参构造器。

5 实现接口

如果枚举类实现了接口,可以给每个实例提供不同的实现方式。

定义一个接口:

java
1
2
3
public interface Feature {
public void showFeature();
}

5.1 普通枚举类

由枚举类来实现接口里的方法,每个枚举类的实例调用的都是同一个方法:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public enum SexEnum implements Feature {
FEMALE(0), MALE(1);

int sex;

private SexEnum(int sex) {
this.sex = sex;
}

public void showSex() {
System.out.println(sex);
}

@Override
public void showFeature() {
System.out.println("性别");
}
}

当每个枚举实例分别实现方法时,在枚举实例调用方法时就会呈现出不同的行为方式:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public enum SexEnum implements Feature {
FEMALE(0) {
@Override
public void showFeature() {
System.out.println("性别女");
}
},
MALE(1) {
@Override
public void showFeature() {
System.out.println("性别男");
}
};

int sex;

private SexEnum(int sex) {
this.sex = sex;
}

public void showSex() {
System.out.println(sex);
}
}

上面这种在枚举值后面紧跟花括号的语法其实是创建匿名内部类的语法,花括号就是类体部分。当创建枚举类的实例时,并不是直接创建,而是相当于创建匿名子类的实例。

5.2 抽象枚举类

抽象枚举类就是在枚举类里定义一个抽象方法,让每个枚举类的实例分别去实现:

java
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
26
public enum SexEnum {
FEMALE(0) {
@Override
public void showFeature() {
System.out.println("性别女");
}
},
MALE(1) {
@Override
public void showFeature() {
System.out.println("性别男");
}
};

int sex;

private SexEnum(int sex) {
this.sex = sex;
}

public void showSex() {
System.out.println(sex);
}

public abstract void showFeature();
}

评论