enum1.產生背景

今天我們將探討 Java 中的另一種數據類型:enum. 這個名字enum來自單詞enumeration。這個數據類型是什麼,它有什麼用?

有時程序員需要創建一個新的數據類型,其可能的值被限制在一個小的固定列表中。

比如一個DayOfTheWeek類型只能取值MONDAY, TUESDAY, WEDNESDAY, ... 一共有7個值。或者一個Month類型只能取值JANUARY, FEBRUARY, MARCH, ... 總共有 12 個值。

當然,您可以使用數字(int類型):1— 星期一,2— 星期二,等等。但是有人可能會不小心將無效值分配給您的變量,例如8or 0

您可能很容易遇到這樣一種情況:一個程序員認為星期幾(或一年中的幾個月)是從零開始編號的,而其他人則希望他們的編號從一開始,等等。

這就是 Java 引入一種由有限值集enum組成的數據類型的原因。


2.聲明類型

聲明一個新的enum數據類型看起來像這樣:

enum TypeName
{
   VALUE1,
   VALUE2,
   VALUE3
}

哪裡TypeName是新類型(類)的名稱,可能的值用逗號分隔並用花括號括起來:Value1, Value2, Value3.

例如,讓我們創建自己的DayOfTheWeek enum

代碼 筆記
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY
}
Day類型

週一
周二
週三
週四
周五
週六
週日

以下是如何為我們的新類型的變量賦值:

Day day = Day.MONDAY;

例子:

代碼 筆記
Day day = Day.FRIDAY;
System.out.println(day);
屏幕輸出將是:
FRIDAY


3.方法enum

一個enum類型有幾個內置方法,其中兩個非常有趣:

靜態values()方法返回該類型所有值的數組enum

代碼 筆記
Day[] days = Day.values();

for (Day day: days)
   System.out.println(day);







System.out.println(days[2]);
變量days存儲一個包含類型值的數組Day(7 個元素)

在屏幕上顯示數組的內容:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

WEDNESDAY

ordinal()方法返回常量的序數。enum你在一個值而不是一個類上調用它enum

代碼 控制台輸出
System.out.println(Day.MONDAY.ordinal());
System.out.println(Day.FRIDAY.ordinal());
System.out.println(Day.SUNDAY.ordinal());
0
4
6


4.轉換為類

實際上,這裡並沒有什麼神奇之處。編譯器只是給了我們一些語法糖。在編譯時,Day枚舉被轉換為普通類:

代碼,簡化版 筆記
public class Day
{
   public static final Day MONDAY = new Day(0);
   public static final Day TUESDAY = new Day(1);
   public static final Day WEDNESDAY = new Day(2);
   public static final Day THURSDAY = new Day(3);
   public static final Day FRIDAY = new Day(4);
   public static final Day SATURDAY = new Day(5);
   public static final Day SUNDAY = new Day(6);

    private static final Day[] array = {MONDAY, TUESDAY,
      WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY};

   private final int value;

   private Day (int value)
   {
      this.value = value;
   }

   public int ordinal()
   {
      return this.value;
   }

   public static Day[] values()
   {
      return array;
   }
}
Dayclass

靜態常量列表包含枚舉







所有值的數組 存儲特定對象 值的變量 該類是私有的,這意味著該類的對像只能在該類內部創建。必須在對像上調用 該方法。 它返回對象的值——字段。該方法返回一個包含類 的所有值的靜態數組Day


Day

DayconstructorDayDay



ordinalDay

value


Day

如果我們從類中刪除所有靜態方法和變量Day,我們將得到以下內容:

代碼 筆記
public class Day
{
  private int value;

  private Day (int value)
  {
    this.value = value;
  }

  public int ordinal()
  {
    return this.value;
  }
}


變量存儲對象value的值對像只能在類內部創建,因為構造函數是. 該方法返回對象的。 Day

DayDayprivate




ordinal()valueDay

換句話說,這裡沒有發生任何可怕的事情。編譯器創建Day類,添加表示值的常量enum,添加必要的方法,並生成類構造函數private。稍後我們將看看構造函數是如何工作的。

希望現在清楚為什麼我們以這種方式為變量賦值:

Day day = Day.MONDAY;

MONDAY只是Day類中的靜態字段(常量)。從類外部訪問靜態方法和字段時,必須在字段或方法的名稱之前指明類名。



5.更多方法enum

每個enum班級都有幾個有趣的特點。

與字符串相互轉換

要將枚舉對象轉換為字符串,您需要調用它的toString()方法。

String str = Day.MONDAY.toString();

要從另一個方向轉換(從字符串到對象Day),您可以使用靜態valueOf()方法:

Day day = Day.valueOf("MONDAY");

它非常方便,在很多情況下都會很有幫助。

轉換為數字並再次返回

您已經知道如何將enum對象轉換為數字:調用ordinal()方法:

int index = Day.MONDAY.ordinal();

要在另一個方向(從數字到對象Day)轉換,您需要一個更透明的結構:

Day day = Day.values()[2];

例子:

代碼 筆記
Day day = Day.MONDAY;
int index = day.ordinal();
Day newDay = Day.values()[index+2];
星期一
獲取星期一的索引: 0
星期一後第 2 天的星期幾

要點:因為enum值是一組固定的常量,所以可以使用 == 比較它們。換句話說,您不能擁有兩個MONDAY具有不同地址的相同對象。每個枚舉值只存在一個實例。這意味著使用 == 比較枚舉變量將始終有效。



6. 將自己的方法添加到enum

因為anenum在編譯時變成了一個普通的類,你可以在裡面聲明方法。這些方法只是簡單地添加到編譯器生成的類中。例如,假設我們希望我們Day enum返回一個枚舉值列表而不是一個數組。

然後我們可以添加以下代碼:

代碼 筆記
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY;

   public static List<Day> asList()
   {
      ArrayList<Day> list = new ArrayList<Day>();

      Collections.addAll(list, values());

      return list;
   }

}








值列表後需要分號。



創建ArrayList對象

添加方法返回的數組中的值values()
返回列表。

現在可以在代碼中調用此方法:

代碼 筆記
List<Day> list = Day.asList();
list變量將存儲 的所有值的列表Day enum