Java枚舉類型

來源:互聯網
上載者:User

     關鍵字enum可以將一組具名的值的有限集合建立為一種新的類型,而這些具名的值可以作為常規的程式組件使用。這些具名的值稱為枚舉值,這種新的類型稱為枚舉類型。

     下面是一個簡單的表示星期幾的枚舉:

1 public enum Day {2     SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY3 }

     在建立enum時,編譯器會自動添加一些有用的特性。比如建立toString()方法以便顯示某個enum執行個體的名字;建立ordinal()方法表示某個特定enum常量的申明順序;values()方法用來按照enum常量的申明順序產生這些常量構成的數組。enum看起來像是一種新的資料類型,除了編譯上面這些特殊的編譯行為,很大程度上可以將enum看成是一個普通的類來處理。這些內容在後面會有詳細的介紹。

public static void main(String[] args) {    System.out.println(Day.class.getSuperclass());    for (Day day : Day.values()) {        System.out.println(day.name() + " ordinal: " + day.ordinal());    }}

class java.lang.Enum

SUNDAY ordinal: 0

MONDAY ordinal: 1

TUESDAY ordinal: 2

WEDNESDAY ordinal: 3

THURSDAY ordinal: 4

FRIDAY ordinal: 5

SATURDAY ordinal: 6

     上面的代碼中輸出了枚舉類型Day的父類及示範了values()、name()、ordinal()三個方法的調用。從輸出結果中可以看到Day的父類是java.lang.Enum,但是在定義Day的時候並沒有通過extends指明繼承java.lang.Enum,也不需要通過extends關鍵字指定。當建立enum時編譯器會產生一個相關的類,這個類會繼承java.lang.Enum。既然枚舉執行個體已經整合了java.lang.Enum,Java又不支援多繼承,所以enum不能再繼承其他的類,但是能實現介面。ordinal()方法返回一個int值,這是每個enum執行個體在申明時的次序,從0開始。

     除了不能繼承自一個enum外,基本上可以將enum看做一個常規的類。也就是說可以向enum中添加方法,比如返回enum自身描述的方法,還可以添加main方法。下面是一個示範enum添加自訂方法和實現介面的例子。

 1 public enum Signal implements ObjectDescription { 2     Red("紅燈", "敢過去就是6分,還要罰款哦"),  3     Yellow("黃燈", "黃燈你也不敢過"),  4     Green("綠燈", "綠燈也得小心過啊"); 5  6     private String name; 7     private String description; 8  9     private Signal(String name, String description) {10         this.name = name;11         this.description = description;12     }13 14     private String getName() {15         return name;16     }17 18     private String getDescription() {19         return description;20     }21 22     @Override23     public String todo() {24         return "Signal類用於表示交通訊號指示燈," + this + "用於表示" + this.getName();25     }26 27     public static void main(String[] args) {28         for (Signal signal : Signal.values()) {29             System.out.println(signal.todo());30         }31         for (Signal signal : Signal.values()) {32             System.out.println(signal.getName() + ": "33                     + signal.getDescription());34         }35     }36 37 }

     注意:如果要自訂方法,那麼必須在enum執行個體序列的最後添加一個分號。同時,Java要求必須先定義enum執行個體,否則編譯時間會報錯。

     enum的構造器無論是不是private,都只能在enum定義的內部使用來建立enum執行個體,一旦enum的定義結束,編譯器就不允許再使用其構造器來建立任何執行個體了。

 

使用介面組織枚舉

     無法使用繼承限制了枚舉的使用,比如需要用enum表示食物,但同時必須分為水果,點心等類型的時候就沒那麼方便的滿足了。

     下面通過在一個介面內部建立實現該介面的枚舉,從而達到對元素進行分類組織的目的。

 1 public interface Food { 2     enum Appetizer implements Food { 3         SALAD, SOUP, SPRING_ROLLS; 4     } 5  6     enum MainCourse implements Food { 7         LASAGNE, BURRITO, PAD_THAI, LENTILS, HUMMOUS, VINDALOO; 8     } 9 10     enum Dessert implements Food {11         TIRAMISU, GELATO, BLACK_fOREST_CAKE, FRUIT;12     }13 14     enum Coffee implements Food {15         BLACK_COFFEE, DECAF_COFFEE, LATTE;16     }17 }

     對於enum而言,實現介面是使其子類化的唯一辦法。通過上面的形式,成功的對不同的食物進行分組,但都是Food。 

 

枚舉的枚舉

     下面是一個枚舉的隨機播放器,是一個工具類。

 1 public class Enums { 2     private static Random rand = new Random(47); 3  4     public static <T extends Enum<T>> T randrom(Class<T> ec) { 5         return random(ec.getEnumConstants()); 6     } 7  8     public static <T> T random(T[] values) { 9         return values[rand.nextInt(values.length)];10     }11 }

     結合工具類及上面Food介面的內容,下面使用枚舉的枚舉實現一個產生隨機菜單的例子。

 1 public enum Course { 2     APPETIZER(Food.Appetizer.class), MAINCOURSE(Food.MainCourse.class), DESSERT( 3             Food.Dessert.class), COFFEE(Food.Coffee.class); 4     private Food[] values; 5  6     private Course(Class<? extends Food> kind) { 7         // 返回枚舉中所有的元素,及所有執行個體構成的數組,如果kind不是枚舉返回null 8         values = kind.getEnumConstants(); 9     }10 11     public Food randomSelection() {12         return Enums.random(values);13     }14 15     public static void main(String[] args) {16         // 產生5份隨機菜單17         for (int i = 0; i < 5; i++) {18             for (Course c : Course.values()) {19                 Food food = c.randomSelection();20                 System.out.println(food);21             }22             System.out.println("--------------------");23         }24     }25 }

     下面給出一個驗證values()方法不是通過父類繼承的方法。

 1 public enum Signal implements ObjectDescription { 2     Red("紅燈", "敢過去就是6分,還要罰款哦"), Yellow("黃燈", "黃燈你也不敢過"), Green("綠燈", "綠燈也得小心過啊"); 3  4     private String name; 5     private String description; 6  7     private Signal(String name, String description) { 8         this.name = name; 9         this.description = description;10     }11 12     private String getName() {13         return name;14     }15 16     private String getDescription() {17         return description;18     }19 20     @Override21     public String todo() {22         return "Signal類用於表示交通訊號指示燈," + this + "用於表示" + this.getName();23     }24 25     public static void main(String[] args) {26         Set<Method> methodSet = new HashSet<Method>();27         Method[] signalMethods = Signal.class.getMethods();28         for (Method m : signalMethods) {29             methodSet.add(m);30         }31         Method[] superClassMethods = Signal.class.getSuperclass().getMethods();32         for (Method m : superClassMethods) {33             methodSet.remove(m);34         }35         System.out.println(methodSet);36     }37 38 }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.