Type Safe Enum
Tiger的改進其實真的稱得上是順應民意,里面的好多特性都可以在兩本Java巨著<<Think In Java>;>;和<<Effective Java>;>;發(fā)現(xiàn)一些端倪.
(不得不承認,<<Think In Java>;>;和<<Effective Java>;>;是Java歷史上最經典的兩本書,多讀多受益)
比如,之前提到過的Genric,在<<Think In Java>;>; 第九章介紹Colletion時就對Genric作出了預期,同時也實現(xiàn)某種形式的Genric(TIJ 2ND,P449-P455).
另外,Think In Java里也提及了利用interface來定義一組常量的方法(P358-P360),不少標準的Java庫類也使用了這種方法(如java.util.zip.ZipConsts.不過,你將會發(fā)現(xiàn),在Tiger里它已經不復存在了)
這種做法叫做Const Interface,大家也許或多或少都使用過.但是,Const Interface的方式在<<Effective Java>;>;受到了極大的否定(Item 17).書里提出了使用Type Safe Enum的方法(Item 21)來取代Const Interface.讓我們對比一下以下兩段代碼
Const Interface
[code]
//SeasonConst.java
// Constant interface pattern - do not use!
public interface SeasonConst {
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int AUTUMN = 3;
public static final int WINTER = 4;
}
//TestConst.java
//using of Constant interface
public class TestConst implements SeasonConst{
public void seasonLiving(int season){
if(season==SPRING){
System.out.println("we BBQ at SPRING");
}
else if(season==SUMMER){
System.out.println("we swim at SUMMER");
}
else if(season==AUTUMN){
System.out.println("we kite at AUTUMN");
}
else if(season==WINTER){
System.out.println("we skate at WINTER");
}
else{
System.out.println("What ?");
}
}
public static void main(String args[]){
TestConst t = new TestConst();
t.seasonLiving(SPRING);
t.seasonLiving(WINTER);
t.seasonLiving(WINTER+1);
//t.sersonLiving(WEEK_DAY.MONDAY);//程序無法和其他常數(shù)完整的區(qū)分
}
}
[/code]
Type Safe Enum
[code]
//SeasonEnum.java
// The typesafe enum (j2sdk1.4)pattern
public class SeasonEnum {
private final String name;
private SeasonEnum(String name) {
this.name = name;
}
public String toString() { return name; }
public static final SeasonEnum SPRING = new SeasonEnum("SPRING");
public static final SeasonEnum SUMMER = new SeasonEnum("SUMMER");
public static final SeasonEnum AUTUMN = new SeasonEnum("AUTUMN");
public static final SeasonEnum WINTER = new SeasonEnum("WINTER");
}
//TestEnum.java
//using of typesafe enum (j2sdk1.4)
public class TestEnum{
public void seasonLiving(SeasonEnum season){
if(season==SeasonEnum.SPRING){
System.out.println("we BBQ at "+season);
}
else if(season==SeasonEnum.SUMMER){
System.out.println("we swim at "+season);
}
else if(season==SeasonEnum.AUTUMN){
System.out.println("we kite at "+season);
}
else if(season==SeasonEnum.WINTER){
System.out.println("we skate at "+season);
}
else{
System.out.println("What ?");
}
}
public static void main(String args[]){
TestEnum t = new TestEnum();
t.seasonLiving(SeasonEnum.SPRING);
t.seasonLiving(SeasonEnum.WINTER);
//t.seasonLiving(WINTER+1);no way to put a season not in the SeasonEnum
}
}
[/code]
可以看出,Type Safe Enum在以下幾個方面優(yōu)于Const Interface
1.不會違背OO繼承的意義.
2.類型安全,不會有無意義的常數(shù)混進正常常數(shù)中
3.保持自己的獨立性,不像Const interface再編譯后就失去了意義
4.可直接用于print
5.作為一個Object,可以擁有自己的方法,變量,可以繼承,implement interface
但是,相對的,Type Safe Enum在使用中也有幾點不利的地方
1.不能直接用于switch
2.必須跟上類名,增加復雜性
3.繁瑣
于是,Tiger中引入了 typesafe Enum和static import ,同時啟用了一個新的關鍵字enum(這也是Tiger中引入的唯一一個關鍵字).再配合上Genric,使得整個結構變得嚴謹而易用.
讓我們還是使用方才的例子來說明吧,先來一個最簡單的例子.
[code]
public class TestEnumTiger1{
public enum SeasonSimpliest {? ? ? ? SPRING,? ? ? ? SUMMER,? ? ? ? AUTUMN,? ? ? ? WINTER}
public void seasonLiving(SeasonSimpliest season){
if(season==SeasonSimpliest.SPRING){
System.out.println("we BBQ at "+season);
}
else if(season==SeasonSimpliest.SUMMER){
System.out.println("we swim at "+season);
}
else if(season==SeasonSimpliest.AUTUMN){
System.out.println("we kite at "+season);
}
else if(season==SeasonSimpliest.WINTER){
System.out.println("we skate at "+season);
}
else{
System.out.println("What ?");
}
}
public static void main(String args[]){
TestEnumTiger1 t = new TestEnumTiger1();
t.seasonLiving(SeasonSimpliest.SPRING);
t.seasonLiving(SeasonSimpliest.WINTER);
System.out.println("the seasong is :"+SeasonSimpliest.SPRING);
//t.seasonLiving(WINTER+1);no way to put a season not in the SeasonEnum
//t.seasonLiving(new SeasonSimpliest("Five Season"));no way to put a season not in the SeasonEnum
}
}[/code]
這里面的常量直接用enum修飾,再加上一個名字和所需常量就可以了.
enum SeasonSimpliest {? ? ? ? SPRING,? ? ? ? SUMMER,? ? ? ? AUTUMN,? ? ? ? WINTER}
不過,不要被這種形式所迷惑,以為enum是一個primtive type,與int,boolean一樣,那就錯了.
讓我們編譯一下這個文件,再看看編譯后的目錄
里面除了有TestEnumTiger1.java,TestEnumTiger1.class之外,還有一個TestEnumTiger1$SeasonSimpliest.class,這就暴露了enum的某些行為方式,它在某種意義上是一個class.
在上面的源碼中,它成了一個inner-class.
OK.讓我們改改代碼,把enum作為一個獨立個體來處理
[code]
//SeasonSimpliest.java
package test;
public enum SeasonSimpliest {SPRING,SUMMER,AUTUMN,WINTER}
[/code]
[code]
//enum & static import
package test;
import static test.SeasonSimpliest.*;
public class TestEnumTiger2{
public void seasonLiving(SeasonSimpliest season){
switch(season){
case SPRING:
System.out.println("we BBQ at "+season);
break;
case SUMMER:
System.out.println("we swim at "+season);
break;
case AUTUMN:
System.out.println("we kite at "+season);
break;
case WINTER:
System.out.println("we skate at "+season);
break;
default:throw new AssertionError("something must be wrong,no such a season");
}
}
public static void main(String args[]){
TestEnumTiger2 t = new TestEnumTiger2();
t.seasonLiving(SPRING);
t.seasonLiving(WINTER);
System.out.println("the season is :"+SUMMER);
//t.seasonLiving(WINTER+1);no way to put a season not in the SeasonEnum
//t.seasonLiving(new SeasonSimpliest("Five Season"));no way to put a season not in the SeasonEnum
}
}
[/code]
為了使整個代碼顯得更加簡潔,我引入import static ,稍后再作更詳細介紹,現(xiàn)在先來看看enum的好處.
1.避免了使用Const interface
2.很簡單的定義方式
3.Type Safe,類型安全的,不會和其他的常量混繞.
4.可以使用switch
5.作為一個Class,它可以有自己Method,Field,也可以implements interface.
為了更好的說明第5點,我給大家展示一個復雜的enum type.
[code]
//SeasonComplex.java
//implements interface,owner method & field
public??enum SeasonComplex implements Comparable<SeasonComplex>; {
? ? ? ? SPRING(1),
? ? ? ? SUMMER(2),
? ? ? ? AUTUMN(3),
? ? ? ? WINTER(4);
private final int seasonNumber;
Season(int value){
? ? ? ? seasonNumber=value;
? ? ? ? }
public int seasonNumber(){
? ? ? ? return seasonNumber;
}
public int compare(Season c){
return seasonNumber - c.seasonNumber;
}
public String description(){
return this+":第"+ seasonNumber +"季";
}
};
[/code]
具體的我就不一一寫清楚,大家好好體會吧.