CodeGym /Java Blog /Toto sisi /Java 中的枚舉類
John Squirrels
等級 41
San Francisco

Java 中的枚舉類

在 Toto sisi 群組發布
你好!在本文中,我們將向您介紹Java 枚舉。想像一下,您被賦予了以下任務:創建一個實現星期幾的類。乍一看,這似乎相當簡單。您的代碼看起來像這樣:

public class DayOfWeek {

   private String title;

   public DayOfWeek(String title) {
       this.title = title;
   }

   public static void main(String[] args) {
       DayOfWeek dayOfWeek = new DayOfWeek("Saturday");
       System.out.println(dayOfWeek);
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
一切似乎都很好,但有一個問題:您可以將任何文本傳遞給DayOfWeek類的構造函數。這意味著有人可以創建一個名為“Frog”、“Cloud”或“azaza322”的星期幾。這顯然不是我們期望的行為,因為一周只有 7 天,而且每一天都有特定的名稱。因此,我們的任務是以某種方式限制DayOfWeek類的可能值的範圍。在 Java 1.5 出現之前,開發人員不得不獨立地發明他們自己的解決方案來解決這個問題,因為該語言沒有現成的解決方案。在那些日子裡,如果程序員需要限制值的數量,他們會這樣做:

public class DayOfWeek {

   private String title;

   private DayOfWeek(String title) {
       this.title = title;
   }

   public static DayOfWeek SUNDAY = new DayOfWeek("Sunday");
   public static DayOfWeek MONDAY = new DayOfWeek("Monday");
   public static DayOfWeek TUESDAY = new DayOfWeek("Tuesday");
   public static DayOfWeek WEDNESDAY = new DayOfWeek("Wednesday");
   public static DayOfWeek THURSDAY = new DayOfWeek("Thursday");
   public static DayOfWeek FRIDAY = new DayOfWeek("Friday");
   public static DayOfWeek SATURDAY = new DayOfWeek("Saturday");

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
以下是您應該注意的事項:
  • 構造函數是私有的。如果構造函數標有private修飾符,則不能用於創建對象。由於該類只有一個構造函數,因此永遠無法創建DayOfWeek對象。

    
    	public class Main {
    
       		public static void main(String[] args) {
          
           			DayOfWeek sunday = new DayOfWeek(); // Error!
       		}
    }
    

  • 當然,該類確實具有所需數量的公共靜態對象,這些對像已正確初始化(使用正確的星期幾名稱)。

    這允許這些對像在其他類中使用。

    
    	public class Person {
    
       		public static void main(String[] args) {
    
           			DayOfWeek sunday = DayOfWeek.SUNDAY;
    
           			System.out.println(sunday);
      		 }
    }
    

    輸出:

    DayOfWeek{title = '星期日'}

這種方法很大程度上解決了這個問題。我們一周有 7 天可供支配,沒有人可以創造新的一天。這個解決方案由 Joshua Bloch 在他的Effective Java一書中提供。順便說一句,那本書非常酷,是所有 Java 開發人員的必讀之書。 如何使用 Enum 類 - 2隨著 Java 1.5 的發布,該語言獲得了針對此類情況的現成解決方案:Java EnumsJava中的枚舉也是一個類。它專門“微調”來解決這樣的問題,即創造一定的有限範圍的價值。Java 的創建者已經有了​​現成的示例(例如,C 已經有了enum),因此他們能夠創建最好的變體。

那麼什麼是 Java 枚舉?

讓我們重溫我們的DayOfWeek示例:

public enum DayOfWeek {

   SUNDAY,
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY
}
現在看起來簡單多了 :) 在內部,我們的Enum有 7 個靜態常量。這就是我們可以用它來實現程序的東西。例如,讓我們編寫一個程序來確定學生今天是否需要上學。我們的學生將有一個每日時間表,由StudentSchedule類表示:

public class StudentSchedule {

   private DayOfWeek dayOfWeek;
   // ... other fields


   public DayOfWeek getDayOfWeek() {
       return dayOfWeek;
   }

   public void setDayOfWeek(DayOfWeek dayOfWeek) {
       this.dayOfWeek = dayOfWeek;
   }
}
schedule 對象的dayOfWeek變量決定今天是哪一天。這是我們的學生班級:

public class Student {

   private StudentSchedule schedule;
   private boolean goToSchool;

   public void wakeUp() {
      
       if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
           System.out.println("Hooray, you can sleep more!");
       } else {
           System.out.println("Damn, time for school again :(");
       }
   }
}
wakeUp()方法中,我們使用Java Enum來確定學生下一步應該做什麼。我們甚至沒有提供有關DayOfWeek中每個字段的詳細信息,我們也不需要:很明顯一周中的幾天應該如何工作。如果我們以當前形式使用它,任何開發人員都會理解我們的代碼中發生了什麼。Enum的另一個便利示例是它的常量可以與 switch 語句一起使用。例如,讓我們編寫一個嚴格飲食的程序,其中按天安排菜餚:

public class VeryStrictDiet {
   public void takeLunch(DayOfWeek dayOfWeek) {
       switch (dayOfWeek) {
           case SUNDAY:
               System.out.println("Sunday Dinner! You can even enjoy something a little sweet today.");
               break;
           case MONDAY:
               System.out.println("Lunch for Monday: chicken noodle soup!");
               break;
           case TUESDAY:
               System.out.println("Tuesday, today it's celery soup :(");
               break;
               //... and so on to the end
       }
   }
}
這是Enums優於 Java 1.5 之前使用的舊解決方案的優勢之一——舊解決方案不能與switch一起使用。 關於枚舉,您還需要了解什麼 Enum是一個真正的類,具有它所包含的所有可能性。例如,如果當前對星期幾的實現不充分,您可以向DayOfWeek添加變量、構造函數和方法:

public enum DayOfWeek {
  
   SUNDAY ("Sunday"),
   MONDAY ("Monday"),
   TUESDAY ("Tuesday"),
   WEDNESDAY ("Wednesday"),
   THURSDAY ("Thursday"),
   FRIDAY ("Friday"),
   SATURDAY ("Saturday");

   private String title;

   DayOfWeek(String title) {
       this.title = title;
   }

   public String getTitle() {
       return title;
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
現在我們的枚舉常量有一個標題字段、getter 和重寫的toString方法。 與普通類相比, Enum有一個嚴重的限制——它不能被繼承。此外,枚舉具有特徵方法:
  • values() :返回Enum中所有值的數組:

    
    public static void main(String[] args) {
       		System.out.println(Arrays.toString(DayOfWeek.values()));
    }
    

    輸出:

    [DayOfWeek{title = 'Sunday'}, DayOfWeek{title = 'Monday'}, DayOfWeek{title = 'Tuesday'}, DayOfWeek{title = 'Wednesday'}, DayOfWeek{title = 'Thursday'}, DayOfWeek{title = '星期五'}, DayOfWeek{title = '星期六'}]

  • ordinal():返回常量的序數。編號從零開始:

    
    	public static void main(String[] args) {
    
       		int sundayIndex = DayOfWeek.SUNDAY.ordinal();
       		System.out.println(sundayIndex);
    }
    

    輸出:

    0

  • valueOf():返回與傳遞的名稱對應的枚舉對象:

    
    public static void main(String[] args) {
       DayOfWeek sunday = DayOfWeek.valueOf("SUNDAY");
       System.out.println(sunday);
    }
    

    輸出:

    DayOfWeek{title = '星期日'}

筆記:我們使用大寫字母來指定枚舉字段。這些是常量,因此它們使用全部大寫而不是駝峰式
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION