Enum是enumeration(列舉)的簡寫形式,包含在java.lang包中.熟悉C, C++, C#, 或 Pascal人應該對列舉有所瞭解,先看個例子:
public enum Season { winter, spring, summer, fall }
一個enum是定義一組值的對象,它可以包括零個或多個值成員.它是屬於enum類型的,一個enum對象中不可有兩個或多個相同的屬性或值.在次之前的java程式員一般是 用介面的方法實現列舉的,如 :
public interface Season {
static winter = 0;
static spring = 1; //etc..
}
引入了enum的java的列舉的編寫方便了許多,只須定義一個enum型的對象.enum對象的值都回自動獲得一個數字值,從0開始,依次遞增.看一個比較簡單的enum實現的例子:
EnumDemo.java
package net.javagarage.enums;
/*
We can loop over the values we put into the enum
using the values() method.
Note that the enum Seasons is compiled into a
separate unit, called EnumDemo$Seasons.class
*/
public class EnumDemo {
/*declare the enum and add values to it. note that, like in C#, we don't use a ; to
end this statement and we use commas to separate the values */
private enum Seasons { winter, spring,
summer, fall }
//list the values
public static void main(String[] args) {
for (Seasons s : Seasons.values()){
System.out.println(s);
}
}
}
運行上述代碼你回得到 以下結果:
winter
spring
summer
fall
Enum的屬性調用:
下面的代碼展示了調用enum對象的方法,這也是它通常的用法:
package net.javagarage.enums;
/*
File: EnumSwitch.java
Purpose: show how to switch against the values in an enum.
*/
public class EnumSwitch {
private enum Color { red, blue, green }
//list the values
public static void main(String[] args) {
//refer to the qualified value
doIt(Color.red);
}
/*note that you switch against the UNQUALIFIED name. that is, "case Color.red:" is a
compiler error */
private static void doIt(Color c){
switch (c) {
case red:
System.out.println("value is " + Color.red);
break;
case green:
System.out.println("value is " + Color.green);
break;
case blue:
System.out.println("value is : " + Color.blue);
break;
default :
System.out.println("default");
}
}
}
為enums添加屬性和方法
enums也可以象一般的類一樣添加方法和屬性,你可以為它添加靜態和非靜態屬性或方法,這一切都象你在一般的類中做的那樣.
package net.javagarage.enums;
/*
File: EnumDemo.java
Purpose: show how to use an enum that also defines its own fields and methods
*/
public class EnumWithMethods {
//declare the enum and add values to it.
public enum Season {
winter, spring, summer, fall;
private final static String location = "Phoenix";
public static Season getBest(){
if (location.equals("Phoenix"))
return winter;
else
return summer;
}
public static void main(String[] args) {
System.out.println(Season.getBest());
}
}
就是這麼的簡單.但是有一點是需要注意的,那就是enums的值列表必須緊跟在enum聲明,不然編譯時間將會出錯.
Enums建構函式:
和類一樣enums也可以有自己的建構函式,如下:
package net.javagarage.enums;
public class EnumConstructor {
public static void main(String[] a) {
//call our enum using the values method
for (Temp t : Temp.values())
System.out.println(t + " is : " + t.getValue());
}
//make the enum
public enum Temp {
absoluteZero(-459), freezing(32),
boiling(212), paperBurns(451);
//constructor here
Temp(int value) {
this.value = value;
}
//regular field?but make it final,
//since that is the point, to make constants
private final int value;
//regular get method
public int getValue() {
return value;
}
}
}
輸出結果是:
absoluteZero is : -459
freezing is : 32
boiling is : 212
paperBurns is : 451
儘管enums有這麼多的屬性,但並不是用的越多越好,如果那樣還不如直接用類來的直接.enums的優勢在定義int最終變數僅當這些值有一定特殊含義時.但是如果你需要的是一個類,就定義一個類,而不是enum.
package testenum;
/**
* @author fubin www.cujava.com
* Enum是enumeration(列舉)的簡寫形式,這個方法用在java中將很很體現出列舉在編程中的作用
* 列舉可以看成一個量有有限的狀態,並把這些狀態表先出來,就是列舉。
* 本例中ProgramFlags是對類及方法的列舉
* Seasons是對變數的定義的列舉
*/
public class EnumBitmapExample {
public static void main(String args[])
{
ProgramFlags flag = ProgramFlags.showErrors;
System.out.println("名稱:"+flag+
"選種的標識: " +flag.ordinal() +
"標識名稱" +flag.name()+
"取值:"+flag.getBitNumber());
System.out.println(Seasons.spring);
}
}
package testenum;
enum ProgramFlags {
showErrors(211),
includeFileOutput(0x02),
useAlternateProcessor(0x04);
private int bit;
ProgramFlags(int bitNumber)
{
bit = bitNumber;
}
public int getBitNumber()
{
return(bit);
}
}
package testenum;
enum Seasons {
winter,
spring,
summer,
fall
}
枚舉類型是JDK5中新加的功能.最近兩天學習了一下,做一下筆記.
Enum在JDK5中和Class是一個層次的,一種資料類型.可以這麼定義:
public enum Grade {
A, B, C, D, F, INCOMPLETE
};
訪問的時候像Grade.A這樣訪問就可以了.這樣可能會優點迷惑人.A就好像是Enum的一個建構函式,Grade.A就返回了一個Enum對象.不是訪問它的屬性或者方法.
下面講一下emun的使用方法.
1.遍曆enum:
for (Grade g : Grade.values()) {
out.println("Allowed value: '" + g + "'");
}
輸出如下:
Allowed Value: 'A'
Allowed Value: 'B'
Allowed Value: 'C'
Allowed Value: 'D'
Allowed Value: 'F'
Allowed Value: 'INCOMPLETE'
自己不太明白這麼做的目的是什麼?到底什麼地方會用到.一般不會對它進行遍曆吧.覺得意義不是特別大
2.switch 語句中使用.
switch的限制比較大,只能用基本類型,不能用對象.JDK5中進行了擴充,可以使用enum對象,下面是一個例子:
StringBuffer outputText = new StringBuffer(student1.getFullName());
switch (student1.getGrade()) {
case A:
outputText.append(" excelled with a grade of A");
break;
case B: // fall through to C
case C:
outputText.append(" passed with a grade of ")
.append(student1.getGrade().toString());
break;
case D: // fall through to F
case F:
outputText.append(" failed with a grade of ")
.append(student1.getGrade().toString());
break;
case INCOMPLETE:
outputText.append(" did not complete the class.");
break;
}
System.out.println(outputText.toString());
說明一下,最好加上default項,這樣對enum進行擴充了,也可以輸出.
3.使用EnumMap,EnumSet.
這樣可以不使用字串作為標識了.下面是範例程式碼:
// Create a map with the key and a String message
EnumMap<AntStatus, String> antMessages =
new EnumMap<AntStatus, String>(AntStatus.class);
// Initialize the map
antMessages.put(AntStatus.INITIALIZING, "Initializing Ant...");
antMessages.put(AntStatus.COMPILING, "Compiling Java classes...");
antMessages.put(AntStatus.COPYING, "Copying files...");
antMessages.put(AntStatus.JARRING, "JARring up files...");
antMessages.put(AntStatus.ZIPPING, "ZIPping up files...");
antMessages.put(AntStatus.DONE, "Build complete.");
antMessages.put(AntStatus.ERROR, "Error occurred.");
// Iterate and print messages
for (AntStatus status : AntStatus.values() ) {
System.out.println("For status " + status + ", message is: " +
antMessages.get(status));
}
枚舉集合的作用類似於特性的集合,或者類似於某個枚舉類型的所有元素的值的子集。EnumSet
類 擁有以下一系列的靜態方法,可以用這些方法從枚舉類型中擷取單個元素:
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType)
public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s)
public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c)
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType)
public static <E extends Enum<E>> EnumSet<E> of(E e)
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest)
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2)
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3)
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4)
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5)
public static <E extends Enum<E>> EnumSet<E> range(E from, E to)
一旦建立了 EnumSet
,就可以像對待其他任何 Set
對象那樣對待這組對象。
4.enum原理:
enum其實都是建立 java.lang.Enum
類的子類,其中,枚舉類型符合通用模式 Class Enum<E> extends Enum<E>>
,而 E
表示枚舉類型的名稱。protected Enum(String name, int ordinal) ,為建構函式,name為定義的名字,映射為字串,ordinal為序數.
比如說上面的Grade 將會映射到下面的建構函式:
new Enum<Grade>("A",0)
new Enum<Grade>("B",0)
new Enum<Grade>("C",0)
new Enum<Grade>("D",0)
new Enum<Grade>("F",0)
new Enum<Grade>("INCOMPLETE",0)
5.預定義建構函式.
建構函式不僅可以是預設的,還可以自己定製,下面是一個執行個體:
enum Grade{
A(90),
B(80),
C(70),
D(60),
F(50);
public int grade;
Grade(int grade){
this.grade=grade;
}
}這樣每一個成績都會對應一個分數.Grade(int grade)是改寫後的建構函式.注意各個建構函式間應該為逗號,非分號.
6.特定於常量的主體
很難理解的一個術語.其實意思大概是可以為每一個枚舉的值進行繼承,繼承自當前這個eunm,把這個方法進行覆寫.可以看下面一個例子.應該很好明白.
enum Grade {
A(90){
public int getGrade(){
return 90;
}
}, B(80), C(70), D(60), F(50);
public int grade;
Grade(int grade) {
this.grade = grade;
}
public int getGrade(){
return 1;
}
}