Java枚舉的幾種使用方式

以前的Java是沒有枚舉的,凡是需要用的時候大家都是用具名int常量來做,於是我們經常能看到類的成員變量有一堆密密麻麻的public static final int,但使用這種整數常量來代替其實會有一些問題,比如:

  1. 當我們得到了一個枚舉的狀態,想打印出狀態時我們只能看到一個數字,要想知道這數字是啥意思還得查;
  2. 當我們使用這個狀態時,有些程度員可能圖方便用數字來填,有可能這數字完全不在枚舉之列編譯也不會發現,比如Toast.makeText(context,"hello",0).show()你把0換成-100也可以,但是-100顯然不是正確的枚舉;
  3. 當我們用整數來枚舉時,得“編”一些數字碼,而有時候就會編出重複的東西但也不會報錯,比如,今天我寫了一個狀態碼叫STATUS_READY=0X12,第二天我同事沒仔細看我的代碼變動,又添加了一個狀態碼STATUS_RESUME=0X12,這就會引發潛在的錯誤。
好了,枚舉類能比較好的解決上述問題,下面就我想到的使用簡單總結一下。

首先,是最簡單的枚舉類型
public enum WeekDay{
		SUN,MON,TUE,WED,THU,FRI,SAT
	}

然後我們看一個接收字符串來轉換成枚舉並使用的例子:
public class EnumDemo {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		System.out.println("enter a weekday in three letters");
		String weekdayString=scanner.nextLine();
		scanner.close();
		WeekDay weekdayEnum = null;
		try {
			weekdayEnum = WeekDay.valueOf(weekdayString.toUpperCase());
		} catch (IllegalArgumentException e) {
			System.out.println("invalid weekday!");
		}
		System.out.println(weekdayEnum.name()+" - rank in declaration:"+weekdayEnum.ordinal());
		switch (weekdayEnum) {
		case SUN:
			// do something
			break;
		case MON:
			break;
		case TUE:
			break;
		case WED:
			break;
		case THU:
			break;
		case FRI:
			break;
		case SAT:
			break;
		default:
			break;
		}

	}

	public enum WeekDay{
		SUN,MON,TUE,WED,THU,FRI,SAT
	}
}
測試一下,運行後輸入sat,打印結果爲:
enter a weekday in three letters
sat
SAT - rank in declaration:6
這裏其實想強調的是枚舉類型有一個靜態方法valueOf()可以將字符串轉換成此類型的枚舉。
如果我們有時候想用整數呢?那我們也可以把整數轉換成枚舉類,下面看這個例子:
public class EnumDemo {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		System.out.println("enter a weekday in number,from zero on");
		int num=scanner.nextInt();
		System.out.println("result is "+WeekDay.values()[num]);
		scanner.close();
	}

	public enum WeekDay{
		SUN,MON,TUE,WED,THU,FRI,SAT
	}
}
運行後輸入2,打印結果爲:
enter a weekday in number,from zero on
2
result is TUE
如果想把枚舉換成整數碼呢,比如要把狀態換成一個數字代碼,那我們可以用
weekDay.ordinal()
這個方法其實代表的是他在枚舉列表中的排行(從0開始),不過這個方法來表示一個狀態碼也不錯嘛。
如果想把這個狀態碼還原回枚舉,就用
WeekDay.values()[num]
枚舉的靜態方法values()會返回一個數組,包含這個枚舉中所有的枚舉值,然後我們用這個數字碼也即排號就能拿到對應的枚舉值了。
看到這裏小夥伴們可能要噴我了,我們的枚舉代碼表可不是從0開始排序那麼簡單原始的,好吧,沒關係,如果這樣也不是不能用枚舉嘛,下面看看如何用寫顯示構造方法的枚舉來實現枚舉與任意整數掛鉤:
public class EnumDemo {

	public static void main(String[] args) {
		//整數轉枚舉
		int code=56;
		System.out.println(WeekDay.getWeekDay(code));
		
		//枚舉轉整數
		WeekDay weekday=WeekDay.FRI;
		System.out.println(weekday.dayCode);
		
	}

	public enum WeekDay{
		SUN(121),MON(78),TUE(56),WED(33),THU(13),FRI(9),SAT(6);
		private int dayCode;//記錄枚舉對應的數字碼
		private WeekDay(int dayCode){
			this.dayCode=dayCode;
		}
		public static WeekDay getWeekDay(int dayCode){
			for(WeekDay weekday:WeekDay.values()){
				if(dayCode==weekday.dayCode){
					return weekday;
				}
			}
			return null;
		}
	}
}
其實,枚舉也是java類,但是其構造方法必須是私有的,我們可以在列舉枚舉時使用帶參數的構造方法,並把參數放到枚舉類裏,這裏其實有個小問題其實我也沒明白,WeekDay裏面的成員變量dayCode明明是private的,但在main方法裏面仍然可以訪問到……希望知道原因的童鞋不吝指點。
下面再說說給枚舉加方法,這個就和普通的類方法差不多了,就是要靈活運用枚舉的幾個重要方法,下面來寫例子,還上那個WeekDay,實現一個方法,返回第二天的WeekDay,上代碼:
public class EnumDemo {

	public static void main(String[] args) {
		WeekDay day=WeekDay.SAT;
		System.out.println(day.nextDay());
		
		day=WeekDay.THU;
		System.out.println(day.nextDay());
		
	}

	public enum WeekDay{
		SUN,MON,TUE,WED,THU,FRI,SAT;
		public WeekDay nextDay(){
			if(ordinal()==WeekDay.values().length-1)
				return SUN;
			else
				return WeekDay.values()[ordinal()+1];
		}
	}
}
最後再說一種用法,就是帶抽象方法的枚舉……囧,這種用法比較詭異,但確實是可以這麼來的,下面舉例,還是那個WeekDay,帶一個抽象的得到全名稱的方法,上代碼:
public class EnumDemo {

	public static void main(String[] args) {
		WeekDay day=WeekDay.MON;
		System.out.println(day.getFullName());
	}

	public enum WeekDay{
		SUN {
			@Override
			public String getFullName() {
				return "Sunday";
			}
		},MON {
			@Override
			public String getFullName() {
				return "Monday";
			}
		},TUE {
			@Override
			public String getFullName() {
				return "Tuesday";
			}
		},WED {
			@Override
			public String getFullName() {
				return "Wednesday";
			}
		},THU {
			@Override
			public String getFullName() {
				return "Thursday";
			}
		},FRI {
			@Override
			public String getFullName() {
				return "Friday";
			}
		},SAT {
			@Override
			public String getFullName() {
				return "Saturday";
			}
		};
		public abstract String getFullName();
	}
}
好了,目前就只能想到這些種用法,如果你在實戰中還發現有其他有趣的用法,請留言給我,大家一起學習哦!






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