前言
程式中經常會使用到一些常數,如果有些常數是共用的,在 Java 中可以定義一個類別或介面來統一管理常數,而其它物件從這些類別或介面上取用常數,如果需要修改常數則可以從這些類別或介面上直接修改,而不用更動到程式的其它部份,這種使用常數的方式在 J2SE 1.4 或之前的版本相當常見。
J2SE 5.0 中新增了「列舉型態」(Enumerated Types),您可以使用這個功能取代之前 J2SE 1.4 或之前版本定義常數的方式,除了常數設置的功能之外,列舉型態還給了您許多編譯時期的檢查功能,但別想的太複雜,列舉型態本質上還是以類別的方式存在,因而它提供了這麼多額外的功能並不奇怪。
一、列舉常數值
在日常生活中,項目固定、值固定,請用列舉。列舉必須寫在類別內部,屬於內部類別。
語法:
編譯器會自動加上存取修飾值 public static final
範例:星期
使用 DJ Java Decompiler 反組譯後,發現 javac 加了很多程式碼。
二、列舉的功能應用
2.1 enum 的相關事項
◉ 列舉的內容值都經過 public final static 的修飾。
◉ 列舉內容一經初始給定後就無法更改。
◉ 列舉值可以用「==」或「equals()」來比較。
◉ 列舉內容值在內部排序與宣告時順序一致。
◉ 列舉內實作了 java.lang.Comparable 介面。
◉ 列舉內容值的資料型別就是該列舉的類別。
2.2 enum 搭配 for 迴圈使用
取出列舉內所有的常數值,可以使用 values() 方法取出一個陣列,回傳 TestEnum2$Week[] 類別。
2.3 enum 的位置索引值
對於每一個列舉成員,您可以使用 ordinal() 方法,依列舉順序得到位置索引,預設以 0 開始。
2.4 enum 搭配 switch 使用
此時需要從列舉取出位置索引,如此就可以搭配 switch 使用。
我們可以使用 valueOf() 方法,Java 會自動使用列舉常數值判斷。
如果您在"switch"中加入了不屬於 Week 中列舉的值,編譯器會回報錯誤。
三、列舉是一個類別
3.1 enum 直接使用自己的建構子方法
列舉型態既然是類別,那麼您可以為它加上建構方法(Constructor)嗎?答案是可以的,但是不得為公開的(public)建構方法,這是為了避免粗心的程式設計人員直接對列舉型態實例化,一個不公開的建構方法可以作什麼?
在列舉 Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday 成員時,您可以一併指定文字描述,這個描述會在建構列舉物件時使用,下個範例中您將之設定給私用成員 msg,在使用 format() 時將它串接返回。
建構子接收兩個參數的範例
3.2 Value-Specific Class Bodies
實作時像是在使用「匿名內部類別」(Anonymous inner class),它讓您可以為每個列舉值定義各自的類本體與方法(Method)實作。
實作覆寫(Overriding) toString() 方法。
3.3 使用 compareTo() 方法比較兩個列舉物件
compareTo() 如果傳回正值,表示設定為引數的列舉物件(inputWeek)其順序在比較的列舉物件(week)之前,負值表示在之後,而 0 則表示兩個互比列舉值的位置是相同的,執行結果如下:
四、總結
使用 enum 來取代常數列舉,列舉型態實際上就是在定義一個類別,兩個公開靜態方法 values() 與 valueOf(),一個私有物件參考變數 $VALUES[],其屬性變數都是 static final。
列舉常數值依照宣告的順序給予位置索引值,可以使用 ordinal() 方法拿取位置索引值。可以使用「==」、「equals()」和「compareTo()」來比較兩個列舉物件。
建構子只能是 private 與 default,其參數個數與列舉常數後的括號參數數量一致。只能覆寫 toString(),其餘方法皆不可以覆寫。
沒有留言:
張貼留言