枚舉小結

最近項目中又用到了枚舉類型,結果還是擺脫不了google查資料的境地,用一次查一次,也慢慢失去了對自己記憶力的自信,看來還是稍微記一下的好。

 

一、什麼是枚舉

      枚舉是 java5中新加的一種類型,但是我們並不陌生,因爲在其它語言中早已存在。說白了就是預先定義一組常量,並作爲一個新的類型,而這種新類型的取值範圍是確定了的,只能在這組常量裏面。

 

      什麼時候使用枚舉呢?一個最重要的依據是取值範圍,一個用枚舉表示的對象,在你的項目或系統裏 的取值範圍應該是確定的,不變的。最著名的例子莫過天用於表示星期幾。

 

二、如何定義

       很簡單,在大括號裏羅列它的值就可以了。

一個表示星期幾的枚舉類:

Java代碼 複製代碼 收藏代碼
  1. public enum Week {   
  2.     SUNDAY,   
  3.     MONDAY,   
  4.     TUESDAY,   
  5.     WEDNESDAY,   
  6.     THURSDAY,   
  7.     FRIDAY,   
  8.     SATURDAY;   
  9. }  
public enum Week {
	SUNDAY,
	MONDAY,
	TUESDAY,
	WEDNESDAY,
	THURSDAY,
	FRIDAY,
	SATURDAY;
}

 

三、用枚舉的好處

我認爲首先它表義,和現實邏輯更接近。從編程上來說,它使我們程序更簡單了。

 

在java中,枚舉出現以前,我們大多數是用靜態變量來實現類似功能的。如:

Java代碼 複製代碼 收藏代碼
  1. public class StaticWeek {   
  2.     public static final int SUNDAY = 0;   
  3.     public static final int MONDAY = 1;   
  4.     public static final int TUESDAY = 2;   
  5.     public static final int WEDNESDAY = 3;   
  6.     public static final int THURSDAY = 4;   
  7.     public static final int FRIDAY = 5;   
  8.     public static final int SATURDAY = 6;   
  9. }  
public class StaticWeek {
	public static final int SUNDAY = 0;
	public static final int MONDAY = 1;
	public static final int TUESDAY = 2;
	public static final int WEDNESDAY = 3;
	public static final int THURSDAY = 4;
	public static final int FRIDAY = 5;
	public static final int SATURDAY = 6;
}

在上面的描述中,我們用StaticWeek.MONDAY 來表示星期一,但這是一種假象,是我們程序人員對自己的一種自我催眠。對於java虛擬機而言它還是int型,和int  1 沒區別。

 

比如有一個類它有一個私有變量dayOfWeek表示星期幾:

Java代碼 複製代碼 收藏代碼
  1. private int dayOfWeek = StaticWeek.SUNDAY;   
  2. private Week dayOfWeek2 = Week.SUNDAY;   
  3.   
  4. public void setDayOfWeek(int dayOfWeek) {   
  5.     this.dayOfWeek = dayOfWeek;   
  6. }  
private int dayOfWeek = StaticWeek.SUNDAY;
private Week dayOfWeek2 = Week.SUNDAY;

public void setDayOfWeek(int dayOfWeek) {
	this.dayOfWeek = dayOfWeek;
}
  • 這個變量有一個初始值StaticWeek.SUNDAY,但是它和int 0 沒區別,只是我們爲了程序好理解,人爲作的一種規則,當然這種規則也給我們帶來了很大的方便。
  • 它還有一個set方法,但它的參數類型是int型,所以它參數值並未侷限於我們定義的七種靜態量。所以你給它一個8,它也不會拒絕,但這顯然也是不合我們定義的邏輯的,所以我們還要驗證參數值是否合法。這裏很不方便,如果傳入的參數一定是合法的該有多好啊,如果接收的參數只能是我定義的七種值就妙不可言了!
Java代碼 複製代碼 收藏代碼
  1. myObj.setDayOfWeek(StaticWeek.FRIDAY);//我們都人爲希望大家都這樣寫,但這需要人的自覺   
  2. myObj.setDayOfWeek(1);//功能同上   
  3. myObj.setDayOfWeek(8);//並未杜絕這種情況的調用,實際上是不合法  
myObj.setDayOfWeek(StaticWeek.FRIDAY);//我們都人爲希望大家都這樣寫,但這需要人的自覺
myObj.setDayOfWeek(1);//功能同上
myObj.setDayOfWeek(8);//並未杜絕這種情況的調用,實際上是不合法
 

用枚舉來實現上面類似的功能:

Java代碼 複製代碼 收藏代碼
  1. private Week dayOfWeek2 = Week.SUNDAY;   
  2.   
  3. public void setDayOfWeek2(Week dayOfWeek2) {   
  4.     this.dayOfWeek2 = dayOfWeek2;   
  5. }  
private Week dayOfWeek2 = Week.SUNDAY;

public void setDayOfWeek2(Week dayOfWeek2) {
	this.dayOfWeek2 = dayOfWeek2;
}

 

Java代碼 複製代碼 收藏代碼
  1. myObj.setDayOfWeek2(Week.FRIDAY);   
  2.            
  3. //下面的調用是不合法,編譯期就會報錯,枚舉限制了調用類型,只能是Week類型,這也確定了它的取值範圍,而且保證是合法的   
  4. myObj.setDayOfWeek2(otherType);  
myObj.setDayOfWeek2(Week.FRIDAY);
		
//下面的調用是不合法,編譯期就會報錯,枚舉限制了調用類型,只能是Week類型,這也確定了它的取值範圍,而且保證是合法的
myObj.setDayOfWeek2(otherType);
  •   首先我們看到我們定義的私有變量就是Week類型的,它是一種類型,而這種類型的取值範圍是我們自己定義的 ,所以它怎麼取值都不會跑出我們的手掌心,如果萬一超出了,你可以去找Sun先生問一下,但首先一定要先確認不是自己的錯。
  • 再看方法,我們把參數類類型設置成了Week類型,這樣就再也不會有人寫出那種讓人不理解的代碼了(myObj.setDayOfWeek(8)) ,因爲有Sun先生爲你把關。

 

三、枚舉使用舉例

一般的使用可以參考上面,唯一值的注意的如何取得一個該類型的實例:類型前綴.要取的值

 

API:values() ,取得一個包括所有值的該枚舉類型數組,如遍歷一個枚舉

Java代碼 複製代碼 收藏代碼
  1. for(Week w:Week.values()){   
  2.     System.out.println(w);   
  3. }  
for(Week w:Week.values()){
	System.out.println(w);
}

 輸出結果:

Java代碼 複製代碼 收藏代碼
  1. SUNDAY   
  2. MONDAY   
  3. TUESDAY   
  4. WEDNESDAY   
  5. THURSDAY   
  6. FRIDAY   
  7. SATURDAY  
SUNDAY
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY

 

API:valueOf() ,取出一個枚舉的一值

Java代碼 複製代碼 收藏代碼
  1. System.out.println(Week.valueOf("MONDAY"));//同Week.MONDAY  
System.out.println(Week.valueOf("MONDAY"));//同Week.MONDAY

 

API.Enum.valueOf(class,String) ,一個靜態方法,取出某個枚舉類型的某個值。

Java代碼 複製代碼 收藏代碼
  1. System.out.println(Enum.valueOf(Week.class"MONDAY"));//同上  
System.out.println(Enum.valueOf(Week.class, "MONDAY"));//同上
 

基本上枚舉就定義了上面三個方法,當然我們還可以編寫自己的方法和自己的構造函數。

 

 

在switch中使用枚舉

我們爲那個有dayOfWeek2變量的類定義一個打印信息的方法

Java代碼 複製代碼 收藏代碼
  1. public void printInfo(){   
  2.         String day;   
  3.            
  4.         switch(this.dayOfWeek2){   
  5.             case SUNDAY:   
  6.                 day = "星期天";   
  7.                 break;   
  8.             case MONDAY:   
  9.                 day = "星期一";   
  10.                 break;   
  11.             case TUESDAY:   
  12.                 day = "星期二";   
  13.                 break;   
  14.             case WEDNESDAY:   
  15.                 day = "星期三";   
  16.                 break;   
  17.             case THURSDAY:   
  18.                 day = "星期四";   
  19.                 break;   
  20.             case FRIDAY:   
  21.                 day = "星期五";   
  22.                 break;   
  23.             case SATURDAY:   
  24.                 day = "星期六";   
  25.                 break;   
  26.             default:   
  27.                 day = "星期幾?";   
  28.         }   
  29.            
  30.         System.out.println("我是"+day);   
  31.     }  
public void printInfo(){
		String day;
		
		switch(this.dayOfWeek2){
			case SUNDAY:
				day = "星期天";
				break;
			case MONDAY:
				day = "星期一";
				break;
			case TUESDAY:
				day = "星期二";
				break;
			case WEDNESDAY:
				day = "星期三";
				break;
			case THURSDAY:
				day = "星期四";
				break;
			case FRIDAY:
				day = "星期五";
				break;
			case SATURDAY:
				day = "星期六";
				break;
			default:
				day = "星期幾?";
		}
		
		System.out.println("我是"+day);
	}
  •  注意,枚舉在case字句中的情況,是不包括枚舉類型的前綴的。

我們使用一下上面的方法:

Java代碼 複製代碼 收藏代碼
  1. myObj.setDayOfWeek2(Week.FRIDAY);   
  2. myObj.printInfo();  
myObj.setDayOfWeek2(Week.FRIDAY);
myObj.printInfo();

 輸出結果:

Java代碼 複製代碼 收藏代碼
  1. 我是星期五  
我是星期五

 

自定義構造函數和自己的方法

改造Week:

Java代碼 複製代碼 收藏代碼
  1. public enum Week {   
  2.     SUNDAY("日"),   
  3.     MONDAY("一"),   
  4.     TUESDAY("二"),   
  5.     WEDNESDAY("三"),   
  6.     THURSDAY("四"),   
  7.     FRIDAY("五"),   
  8.     SATURDAY("六");   
  9.        
  10.     private String name;   
  11.        
  12.     Week(String name){   
  13.         this.name = "星期"+name;   
  14.     }   
  15.        
  16.     public String toString(){   
  17.         return this.name;   
  18.     }   
  19. }  
public enum Week {
	SUNDAY("日"),
	MONDAY("一"),
	TUESDAY("二"),
	WEDNESDAY("三"),
	THURSDAY("四"),
	FRIDAY("五"),
	SATURDAY("六");
	
	private String name;
	
	Week(String name){
		this.name = "星期"+name;
	}
	
	public String toString(){
		return this.name;
	}
}

 如上,枚舉類型可以自定義自己的構造函數,自己的私有變量,自己的方法,重寫方法。

 

根據改造的類我們可以重寫上面打印信息方法printInfo():

Java代碼 複製代碼 收藏代碼
  1. public void printInfo2(){   
  2.     System.out.println("我是"+this.dayOfWeek2.toString());   
  3. }  
public void printInfo2(){
	System.out.println("我是"+this.dayOfWeek2.toString());
}
 

枚舉的構造函數

  • 構造函數前面是不能有修飾符的,或者你只能寫private,即不允許我們人爲調用的
  • 當定義一個枚舉類型時,實際上已經確定了它的實例對象,如Week, 只有七個實例對象
  • 實例對象的構造,也是我們預先定義好的,如Week.MONDAY對象,它的構造:MONDAY("一“),而括號裏的字符串就是我們傳到構造函數的參數。
  • 何時構造,枚舉類型的所有實例是一起構造的,當我們初次使用某個實例時。如:當我們第一次使用任何一個Week實例時,都會構造七個實例。

      

更改構造函數,增加一個輸出

Java代碼 複製代碼 收藏代碼
  1. Week(String name){   
  2.         System.out.println(name);//在初次使用時,所有值的構造會調一往遍   
  3.         this.name = "星期"+name;   
  4.     }  
Week(String name){
		System.out.println(name);//在初次使用時,所有值的構造會調一往遍
		this.name = "星期"+name;
	}

 當我們第一次使用Week的實例時:

Java代碼 複製代碼 收藏代碼
  1. System.out.println("3");   
  2. myObj.setDayOfWeek2(Week.FRIDAY);   
  3. System.out.println("4");  
System.out.println("3");
myObj.setDayOfWeek2(Week.FRIDAY);
System.out.println("4");

 輸出結果

Java代碼 複製代碼 收藏代碼
  1. 3  
  2. 日   
  3. 一   
  4. 二   
  5. 三   
  6. 四   
  7. 五   
  8. 六   
  9. 4  
3
日
一
二
三
四
五
六
4

 

 

三、總結完畢

本文鏈接: http://kino.iteye.com/blog/204949 轉載請註明出處,謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章