Java 枚举 (Enumeration)

2025年4月15日 | 阅读 11 分钟

Java 枚举 (Enumeration) 是一种数据类型,用于表示一组固定的常量。与 C/C++ 不同,Java 中的枚举功能更强大。根据 Java 命名约定,所有常量都应大写。因此,我们使用大写字母表示枚举常量。Java 枚举常量隐式地是 static 和 final 的。它自 JDK 1.5 起可用。

枚举示例

天数: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, and SATURDAY

方向: NORTH, SOUTH, EAST, and WEST

季节: SPRING, SUMMER, WINTER, and AUTUMN or FALL

颜色: RED, YELLOW, BLUE, GREEN, WHITE, and BLACK

尺寸: SMALL, MEDIUM, LARGE, EXTRALARGE

行星: MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE

月份: JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER

我们可以看到,所有的枚举都有固定的值。

定义枚举

Java 提供了 enum 关键字来定义枚举数据类型。我们可以将枚举定义在类内部或类外部,因为它类似于类。Java 枚举内部继承了 Enum 类,因此它不能继承任何其他类,但它可以实现多个接口。我们可以在 Java 枚举中拥有字段、构造函数、方法和 main() 方法。

语法

示例

枚举常量末尾的分号 (;) 是可选的。例如

Java 枚举的这两种定义方式是相同的。大括号内的这些值称为 枚举常量

将枚举用作变量

我们也可以为枚举类型创建一个变量。例如,

在这里,cloth 是 Size 类型的一个变量。它有四个值。

Java 枚举示例

在类外部定义枚举

示例

编译并运行

输出

NORTH
WEST

在类内部定义枚举

示例

编译并运行

输出

WINTER
SPRING
SUMMER
FALL

枚举内部的 main() 方法

如果我们将 main() 方法放在枚举内部,我们可以直接运行该枚举,就像我们在下面的代码中所展示的那样。

示例

编译并运行

输出

WINTER

将枚举与 switch 语句结合使用

示例

编译并运行

输出

Monday

将枚举用作变量

示例

编译并运行

输出

Get ready...

为枚举常量初始化特定值

如前所述,枚举可以有字段、构造函数和方法。枚举常量的初始值从 0, 1, 2, 3 开始。但是,我们可以通过定义字段和构造函数来为枚举常量初始化特定值。

示例

编译并运行

输出

WINTER 5
SPRING 10
SUMMER 15
FALL 20

注意:枚举类型的构造函数是私有的。如果我们不声明私有构造函数,Java 编译器会在内部创建一个私有构造函数。除此之外,它还会在编译时在枚举中添加 values()、valueOf() 和 ordinal() 方法。它在内部为枚举创建一个 static 和 final 类。

编译器会为上面的枚举代码片段生成以下内部代码。

在 if 语句中使用枚举

由于 Java 枚举是常量,指向枚举常量的变量必须经常与其他枚举类型中的其他可能常量进行比较。

语法

示例

在此示例中,RED、YELLOW 和 GREEN 是 TrafficLight 枚举定义的三个常量。if-else 语句检查信号的当前值,然后执行适当的操作。

示例

编译并运行

输出

Get ready...

Java 枚举迭代

Java 内置的 values() 函数通过返回一个包含枚举中定义的所有常量的数组,可以轻松地进行枚举迭代。它使我们能够使用常规 for 循环或增强 for 循环来遍历所有枚举值。当我们想显示所有可能选中的选项、对每个值执行操作或将输入与指定常量进行检查时,枚举迭代非常有用。

语法

示例

此示例使用 Day 枚举列出了所有星期。for 循环使用 Day.values() 遍历并输出每个枚举常量。当处理菜单、下拉菜单或对特定枚举常量执行操作而不对其进行硬编码时,此方法非常有用。

示例

编译并运行

输出

The Days of the week are:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

Java 枚举类

与传统类相比,枚举旨在定义一个已知且有限的值集合。尽管它们看起来很简单,但枚举本身就是 Java 类。当我们创建 Enum 类时,编译器会为每个枚举常量创建一个实例(对象)。此外,默认情况下,所有枚举常量都是 public static final。

这是所有枚举类型的通用基类。它包含了编译器隐式声明的方法的描述。

语法

Enum 类的方法

枚举类有一些易于访问的预定义方法。它们如下。

方法描述
clone()它抛出 CloneNotSupportedException。
compareTo(E o)它将此枚举与指定的对象进行排序比较。
equals(Object others)如果指定对象与此枚举常量相等,则返回 true。
finalize()枚举类不能有 finalize 方法。
getDeclaringClass()它返回与此枚举常量对应的枚举类型的 Class 对象。
hashCode()它返回此枚举常量的哈希码。
name()它返回此枚举常量的名称,与在枚举声明中声明的完全相同。
ordinal()它返回此枚举常量的序数(在枚举声明中的位置,初始常量被分配序数零)。
toString()它返回此枚举常量的名称,如声明中所包含的。
valueOf(Class<T> enumType, String name)它返回指定枚举类型中名称为指定名称的枚举常量。

使用枚举类方法

示例

编译并运行

输出

The ordinal() values are:
MONDAY -> ordinal: 0
TUESDAY -> ordinal: 1
WEDNESDAY -> ordinal: 2
THURSDAY -> ordinal: 3
FRIDAY -> ordinal: 4
SATURDAY -> ordinal: 5
SUNDAY -> ordinal: 6

 compareTo() example:
MONDAY vs FRIDAY: -4
SUNDAY vs SUNDAY: 0

toString() example:
MONDAY says: Start of the work week...
TUESDAY says: Work in progress...
WEDNESDAY says: Mid of the week...
THURSDAY says: About to Complete...
FRIDAY says: Last day of the work week
SATURDAY says: Weekend!
SUNDAY says: Rest day

name() example:
Enum constant name: THURSDAY

valueOf() example:
Converted from string: FRIDAY

values() iteration:
Start of the work week... (MONDAY)
Work in progress... (TUESDAY)
Mid of the week... (WEDNESDAY)
About to Complete... (THURSDAY)
Last day of the work week (FRIDAY)
Weekend! (SATURDAY)
Rest day (SUNDAY)

枚举与 Enum 之间的区别

enum枚举
它是一个关键字。它是一个属于 java.lang 包的抽象类。
它允许创建枚举类型。它提供了枚举类型的功能。
它自动扩展 Enum 类。它扩展了 Object 类。
它不提供任何方法。它提供 valueOf()、ordinal()、toString()、name() 等方法。

为什么 Java 中的枚举功能强大?

  • 代码清晰度: 使用枚举可以使我们的代码更具可读性和自解释性。例如,与其使用整数常量或字符串来表示星期几,不如使用 Day.MONDAY、Day.TUESDAY 等。
  • 类型安全: 枚举强制执行类型安全,这意味着您不能为枚举变量分配任意值。它有助于在编译时而不是运行时捕获错误。
  • 维护: 如果我们需要从一个集合中添加或删除常量,我们可以在枚举声明中轻松完成。更改将传播到我们的代码库中,确保一致性。
  • 避免魔术数字/字符串: 枚举有助于防止代码中散布“魔术数字”或字符串。相反,我们有一个中心位置定义了所有可能的值。

要记住的重要事项

  • 类型安全: 枚举通过将可能的值限制为预定义集合来提高类型安全性。这意味着我们不能为枚举变量分配任意值。
  • Switch 语句: 枚举通常用于 switch 语句,以使代码更清晰简洁。与使用整数或字符串相比,带有枚举的 switch 语句更不容易出错。
  • 遍历枚举: values() 方法允许轻松遍历所有枚举常量。它返回一个包含枚举所有值的数组。
  • 定义枚举: 枚举可以定义在类内部或外部。最后一个枚举常量后的分号是可选的。
  • 初始化值: 枚举可以拥有字段、构造函数和方法。您可以使用构造函数为枚举常量指定初始值。它允许枚举的定义和使用更加灵活。
  • 私有构造函数: 枚举构造函数默认是私有的。它防止外部实例化,并确保枚举实例是常量。
  • 抽象方法: 枚举可以包含抽象方法,每个枚举常量都可以覆盖。它允许枚举将行为与每个常量关联。
  • 在 Switch 语句中的使用: Switch 语句可以应用于枚举,使代码更具可读性和可维护性,尤其是在处理固定选项集时。

结论

总而言之,Java 枚举提供了一种强大的机制来表示程序中的一组固定常量。它们通过将相关常量封装到单个数据类型中,增强了代码的清晰度、类型安全性和可维护性。Java 枚举可以轻松遍历、在 switch 语句中使用以及使用特定值进行初始化,从而提供了灵活性和易用性。

Java 枚举常见问题解答

1. Enum 类中的 valueOf() 方法有什么作用?

答案: Java 编译器在创建枚举时会内部添加 valueOf() 方法。valueOf() 方法返回给定常量枚举的值。

2. Enum 类中的 ordinal() 方法有什么作用?

答案: Java 编译器在创建枚举时会内部添加 ordinal() 方法。ordinal() 方法返回枚举值的索引。

3. 我们可以使用 new 关键字创建枚举的实例吗?

答案: 不可以,因为它只包含私有构造函数。

4. 为什么使用枚举?

答案: 在 Java 中,引入枚举是为了取代 int 常量的使用。假设我们使用了一组 int 常量。

这里,如果我们打印常量,就会出现问题。因为只打印数字,这可能没有帮助。

所以,我们不使用 int 常量,而是直接使用枚举。例如,

这使得我们的代码更具直观性。

5. 枚举可以有抽象方法吗?

答案: 是的,当然!我们可以有抽象方法,并可以提供这些方法的实现。

Java 枚举选择题

1. 在 Java 中声明枚举使用哪个关键字?

  1. class
  2. int
  3. const
  4. enum

答案 4)

解释: Java 提供了 enum 关键字来定义枚举数据类型。我们可以将枚举定义在类内部或类外部,因为它类似于类。


2. 枚举构造函数默认是 _________?

  1. public
  2. private
  3. protected
  4. final

答案 2)

解释: 枚举构造函数默认是私有的。它防止外部实例化,并确保枚举实例是常量。


3. 以下哪种是定义枚举的正确方式?

  1. enum Direction {NORTH, EAST, WEST, SOUTH;}
  2. enum Direction {north, east, west, south}
  3. enum Direction {North, East, West, South}
  4. enum Direction NORTH, EAST, WEST, and SOUTH;

答案 1)

解释:Java 枚举 (Enumeration) 是一种数据类型,用于表示一组固定的常量。根据 Java 命名约定,所有常量都应大写。因此,我们使用大写字母表示枚举常量。


4. 当我们尝试直接打印枚举常量时会发生什么?

  1. 会抛出错误
  2. 它打印序数值
  3. 它打印常量的名称
  4. 它打印枚举常量的完全限定类名

答案 3)

解释: 当我们尝试直接打印枚举常量时,它会打印常量的名称。


5. 枚举类型安全吗?

  1. 是的
  2. 不能
  3. 在某些情况下
  4. 以上都不是

答案 1)

解释: 枚举通过将可能的值限制为预定义集合来提高类型安全性。这意味着我们不能为枚举变量分配任意值。


下一主题Java 注解