声明并使用基本枚举
枚举可以被认为是密封类的语法糖,它只在编译时被实例化多次以定义一组常量。
列出不同季节的简单枚举将声明如下:
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
虽然枚举常量不一定需要全部大写,但 Java 约定是常量的名称完全是大写的,单词用下划线分隔。
你可以在自己的文件中声明枚举:
/**
* This enum is declared in the Season.java file.
*/
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
但是你也可以在另一个类中声明它:
public class Day {
private Season season;
public String getSeason() {
return season.name();
}
public void setSeason(String season) {
this.season = Season.valueOf(season);
}
/**
* This enum is declared inside the Day.java file and
* cannot be accessed outside because it's declared as private.
*/
private enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
最后,你不能在方法体或构造函数中声明枚举:
public class Day {
/**
* Constructor
*/
public Day() {
// Illegal. Compilation error
enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
public void aSimpleMethod() {
// Legal. You can declare a primitive (or an Object) inside a method. Compile!
int primitiveInt = 42;
// Illegal. Compilation error.
enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
Season season = Season.SPRING;
}
}
不允许重复的枚举常量:
public enum Season {
WINTER,
WINTER, //Compile Time Error : Duplicate Constants
SPRING,
SUMMER,
FALL
}
枚举的每个常量默认为 public
,static
和 final
。由于每个常量都是 static
,因此可以使用枚举名称直接访问它们。
枚举常量可以作为方法参数传递:
public static void display(Season s) {
System.out.println(s.name()); // name() is a built-in method that gets the exact name of the enum constant
}
display(Season.WINTER); // Prints out "WINTER"
你可以使用 values()
方法获取枚举常量数组。保证值在返回的数组中按声明顺序排列:
Season[] seasons = Season.values();
注意:此方法在每次调用时都会分配一个新的值数组。
迭代枚举常量:
public static void enumIterate() {
for (Season s : Season.values()) {
System.out.println(s.name());
}
}
你可以在 switch
语句中使用枚举:
public static void enumSwitchExample(Season s) {
switch(s) {
case WINTER:
System.out.println("It's pretty cold");
break;
case SPRING:
System.out.println("It's warming up");
break;
case SUMMER:
System.out.println("It's pretty hot");
break;
case FALL:
System.out.println("It's cooling down");
break;
}
}
你还可以使用 ==
比较枚举常量:
Season.FALL == Season.WINTER // false
Season.SPRING == Season.SPRING // true
比较枚举常量的另一种方法是使用如下的 equals()
,这被认为是不好的做法,因为你很容易陷入陷阱,如下所示:
Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error
此外,虽然 enum
中的实例集不能在运行时更改,但实例本身并不是固有不可变的,因为与任何其他类一样,enum
可以包含可变字段,如下所示。
public enum MutableExample {
A,
B;
private int count = 0;
public void increment() {
count++;
}
public void print() {
System.out.println("The count of " + name() + " is " + count);
}
}
// Usage:
MutableExample.A.print(); // Outputs 0
MutableExample.A.increment();
MutableExample.A.print(); // Outputs 1 -- we've changed a field
MutableExample.B.print(); // Outputs 0 -- another instance remains unchanged
但是,一个好的做法是使 enum
实例不可变,即当它们没有任何额外的字段或者所有这些字段都标记为 final
并且它们本身是不可变的。这将确保在应用程序的生命周期内,enum
不会泄漏任何内存,并且在所有线程中使用其实例是安全的。
枚举隐含地实现了 Serializable
和 Comparable
,因为 Enum
类具有:
public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable