枚舉也是JDK5.0的新特性。html
JDK5.0加入了一個全新類型的「類」——枚舉類型。java
爲此引入了一個新的關鍵字enum。api
能夠這樣來定義一個枚舉類型:數組
public enum Color { Red, White, Blue, }
而後能夠這樣來使用:oracle
Color myColor = Color.Red;
枚舉類型提供了兩個有用的靜態方法values()和valueOf()。this
values()返回枚舉全部成員的數組。spa
values()方法的使用:code
//values()方法的使用 for(Color color : Color.values()) { System.out.println(color); }
將輸出:視頻
Red
White
Blue
即values()輸出定義在Color中的全部枚舉類型。htm
而valueOf()將字符串轉換成枚舉值。
枚舉能夠用在switch語句中。
例子:
public class EnumTest { public static void doOperation(OpConstant opConstant) { switch (opConstant) { case TURN_LEFT: System.out.println("向左轉"); break; case TURN_RIGHT: System.out.println("向右轉"); break; case SHOOT: System.out.println("射擊"); break; default: break; } } public static void main(String[] args) { doOperation(OpConstant.SHOOT); } } enum OpConstant { TURN_LEFT, TURN_RIGHT, SHOOT, }
先看一個例子:
public enum Coin { penny("hello"), nickle("world"), dime("welcome"), quarter("hello world"); private String value; public String getValue() { return value; } Coin(String value) { this.value = value; } public static void main(String[] args) { Coin coin = Coin.quarter; System.out.println(coin.getValue()); } }
定義枚舉類型時本質上就是在定義一個類別,只不過不少細節由編譯器幫您完成,因此某種程度上,enum關鍵字的做用就像是class或interface。
當您使用「enum」定義枚舉類型時,實質上您定義出來的類型繼承自java.lang.Enum類型,而每一個枚舉的成員其實就是您定義的枚舉類型的一個實例(Instance),它們都被預設爲final,因此您沒法改變它們,它們也是static成員,因此您能夠經過類型名稱直接使用它們,固然最重要的,它們都是公開的(public)。即枚舉中的每一個成員默認都是public static final的。
枚舉的本質:
每一個枚舉的成員其實就是您定義的枚舉類型的一個實例(Instance)。
當定義了一個枚舉類型後,在編譯的時候就可以肯定該枚舉類型有多少個實例,這些對象的名字是什麼。在運行期間沒法再使用該枚舉類型建立新的實例。
寫下面一個程序:
public class ShowEnum { public static void main(String[] args) { enumCompareTo(OpConstant.valueOf(args[0])); } public static void enumCompareTo(OpConstant constant) { System.out.println(constant); //當前輸入參數跟每個枚舉中的類型比較,並輸出比較結果 for(OpConstant c : OpConstant.values()) { System.out.println(constant.compareTo(c)); } } }
而後在Run Configurations裏面傳入參數SHOOT,輸出以下:
SHOOT
2
1
0
若是傳入參數TURN_RIGHT:
TURN_RIGHT
1
0
-1
這個程序用於比較枚舉成員誰在前誰在後,當輸入SHOOT時,SHOOT和每一個值比較時,它在TURN_LEFT後面兩位,在TURN_RIGHT後面一位,和本身比較輸出爲0。
例子:
public class ShowEnum2 { public static void main(String[] args) { for(OpConstant c: OpConstant.values()) { System.out.printf("%d, %s, %n", c.ordinal(), c); } } }
輸出:
0, TURN_LEFT,
1, TURN_RIGHT,
2, SHOOT,
EnumSet的名稱說明了其做用,它是在J2SE 5.0後加入的新類別,能夠協助您創建枚舉值的集合,它提供了一系列的靜態方法,可讓您指定不一樣的集合創建方式。
EnumSet有多重重載的of()方法,用於構造含有指定枚舉對象的枚舉集合。
與之對應的有complementOf()方法,返回某個枚舉集合的補集。
noneOf()方法構造一個指定枚舉類型的空枚舉集合。以後能夠用add()方法加入元素。
copyOf()方法有兩種重載形式,一種形式的參數爲枚舉集合EnumSet,另外一種方式的參數爲Collection。說明能夠利用集合來構造枚舉集合,注意若是Collection中有重複元素,只有一個會被加入枚舉集合。
下面的代碼例子中使用了這些方法:
import java.util.List; import java.util.ArrayList; import java.util.EnumSet; import java.util.Iterator; enum FontConstant { Plain, Bold, Italic, Hello, } public class EnumSetDemo { public static void main(String[] args) { System.out.println("--------------of()-----------------"); // of()方法,構造含有指定元素的枚舉集合 EnumSet<FontConstant> enumSet = EnumSet.of(FontConstant.Plain, FontConstant.Bold); showEnumSet(enumSet); System.out.println("------------complementOf()---------------"); // complementOf()方法,構造指定枚舉集合的補集 showEnumSet(EnumSet.complementOf(enumSet)); System.out.println("--------------noneOf()-----------------"); // noneOf()方法構造一個指定枚舉類型的空枚舉集合 EnumSet<FontConstant> enumSet2 = EnumSet.noneOf(FontConstant.class); enumSet2.add(FontConstant.Italic); showEnumSet(enumSet2); System.out.println("---------------copyOf()------------------"); // copyOf()方法的一種重載能夠由集合構造枚舉集合 // 先構造一個List List<FontConstant> list = new ArrayList<FontConstant>(); list.add(FontConstant.Bold); list.add(FontConstant.Italic); list.add(FontConstant.Plain); list.add(FontConstant.Bold); // 而後使用copyO方法構造一個EnumSet showEnumSet(EnumSet.copyOf(list)); } public static void showEnumSet(EnumSet<FontConstant> enumSet) { for (Iterator<FontConstant> iter = enumSet.iterator(); iter.hasNext();) { System.out.println(iter.next()); } } }
EnumMap的聲明是:Class EnumMap<K extends Enum<K>,V>,代表其中的Key是枚舉類型。
使用例子以下:
import java.util.EnumMap; import java.util.Map; public class EnumMapDemo { public static void main(String[] args) { Map<Action, String> map = new EnumMap<Action, String>(Action.class); map.put(Action.TURN_LEFT, "向左轉"); map.put(Action.SHOOT, "射擊"); map.put(Action.TURN_RIGHT, "向右轉"); for (Action action : Action.values()) { System.out.println(map.get(action)); } } } enum Action { TURN_LEFT, TURN_RIGHT, SHOOT, }
張龍老師視頻教程。
Enum類官方文檔:
http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html
EnumSet類:
http://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html
EnumMap類:
http://docs.oracle.com/javase/7/docs/api/java/util/EnumMap.html