枚舉類簡要介紹
枚舉類的特點
- 枚舉類的構造器默認被private修飾,如果顯式指定,也只能用private來修飾,不然會報錯。
- 枚舉類的實例必須在第一行顯式列出,不然無法生成枚舉實例,枚舉實例就是枚舉值。
- 枚舉值默認被public final static修飾。枚舉類默認被final修飾,無法被繼承。
- 枚舉值可以看作靜態常量對象,除了擁有常量的特性外,還和對象一樣可以調用方法、成員變量。
- 和普通類比起來,枚舉類對象數量在第一行就被固定下來了,不能隨意創建。
public enum Color {
RED, GREEN, BLUE;
}
//編譯上面枚舉類後,會生成對應的字節碼文件:Color.class
通過上面代碼,可以看出編譯後的枚舉類和普通類大致差不多,只是用法稍有不同。我們再來看一下,列出枚舉值時無需指定類型,平時定義常量時是要指定類型的,在上面關於枚舉類的特點中,說過枚舉值就是枚舉類對象,所以列出枚舉值就是在創建對象,這會使用到構造器,這裏的構造器是默認的,這時候看一下父類代碼: //父類Enum的構造器
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
枚舉類的用法
boolean |
equals(Object other) 當指定對象等於此枚舉常量時,返回 true。 |
|
protected void |
finalize() 枚舉類不能有 finalize 方法。 |
|
Class<E> |
getDeclaringClass() 返回與此枚舉常量的枚舉類型相對應的 Class 對象。 |
|
int |
hashCode() 返回枚舉常量的哈希碼。 |
|
String |
name() 返回此枚舉常量的名稱,在其枚舉聲明中對其進行聲明。 |
|
int |
ordinal() 返回枚舉常量的序數(它在枚舉聲明中的位置,其中初始常量序數爲零)。 |
|
String |
toString() 返回枚舉常量的名稱,它包含在聲明中。 |
|
static
|
valueOf(Class<T> enumType,String name) 返回帶指定名稱的指定枚舉類型的枚舉常量。 |
System.out.println(Color.RED.ordinal());
System.out.println(Color.GREEN.ordinal());
System.out.println(Color.BLUE.ordinal());
//輸出序數
0
1
2
這裏的序數就是定義枚舉值時自動爲其生成的,理論上來說可以看作是它們的初始值,但提供的數據較少,所以要爲枚舉值附加更多屬性時,可以創建成員變量,使用構造器來賦值。其他方法的話都比較簡單,在此省略示例代碼。public enum Color {
RED, GREEN, BLUE; //列出枚舉值, 枚舉類實例
//定義實例變量和靜態變量
private int a = 10;
private static int b = 100;
//定義方法
public int getA() {
return this.a;
}
public static void main(String[] args) {
Color.RED.a = 20;
Color.RED.b = 101;
Color.GREEN.a = 30;
Color.GREEN.b = 102;
System.out.println("RED.a = " + Color.RED.getA());
System.out.println("GREEN.a = " + Color.GREEN.getA());
//RED.a = 20
//GREEN.a = 30
}
}
RED(15), GREEN(30), BLUE(45); //爲枚舉值的實例變量賦值
//定義實例變量
private int a = 10;
//枚舉類的構造器
private Color(int a) {
this.a = a;
}
//測試
public static void main(String[] args) {
System.out.println(Color.RED.a);
System.out.println(Color.GREEN.a);
System.out.println(Color.BLUE.a);
}
上面只是定義了3個枚舉值,每次獲取值時就顯得很麻煩了,而且重複代碼太多,這時就可以使用values()方法返回枚舉類所有實例,轉成枚舉數組。但在Enum源碼中並沒有該方法,這個問題我也不清楚.....,改進後如下://使用values()來循環獲取屬性值。但獲取屬性值最好是用getXxx()來完成
public static void main(String[] args) {
for(Color c : Color.values()) {
System.out.println(c.a);
}
}
枚舉類應用場景
1.最常用到的當屬常量,例如定義各類狀態時,使用枚舉類可以把相關聯的常量放在一個枚舉類中,並能根據需求來增加屬性和方法。
public enum Sex {
MAN("男") , MALE("女");
private String sex;
private Sex(String sex) {
this.sex = sex;
}
//重寫toString(),返回枚舉值的sex屬性
@Override
public String toString() {
return this.sex;
}
public static void main(String[] args) {
System.out.println(Sex.MAN.toString());
System.out.println(Sex.MALE.toString());
//輸出結果
男
女
}
相較於常量而言,枚舉類可以另加靈活化,還能對常量進行統一管理。 public static void main(String[] args) {
//得到枚舉數組
SeasonEnum[] se = SeasonEnum.values();
//隨機獲得其中一個枚舉
SeasonEnum rand = Test.getRandomEnum(se);
switch(rand) {
case SPRING:
System.out.println(rand + ", 是" + rand.getSeason());
break;
case SUMMER:
System.out.println(rand + ", 是" + rand.getSeason());
break;
case AUTUMN:
System.out.println(rand + ", 是" + rand.getSeason());
break;
case WINTER:
System.out.println(rand + ", 是" + rand.getSeason());
break;
}
}
/** 根據指定的枚舉數組來隨機獲得其中一個枚舉 */
public static <T extends Enum> T getRandomEnum(T[] enumArr) {
int index = (int)(Math.random() * enumArr.length); //生成的下標在枚舉數組長度範圍之內
T rs = enumArr[index];
return rs;
}
3.枚舉類可以在接口中定義,也可以定義在類裏面,訪問權限的使用和內部類一樣,等於使用內部類來維護一些常量的使用。
//能定義在接口中
interface testEnum{
enum State{
ON, OFF;
}
}
//定義成內部枚舉類
public class Test {
enum State{
ON, OFF;
}
}