Java枚舉(用Java普通類模擬枚舉的實現原理及JDK枚舉API使用示例)
枚舉的特點:
◆類型安全(Type Safety)
◆緊湊有效的枚舉數值定義(Compact, Efficient Declaration of Enumerated Values)
◆無縫的和程序其它部分的交互操作(Seamless integration with other language features)
◆運行的高效率(Runtime efficiency)
詳情請看:https://www.51cto.com/specbook/11/32877.htm
1、使用Java普通類模擬枚舉的實現原理
import java.util.HashMap;
import java.util.Map;
/**
* 模擬星期中的表示的天,每個星期天都表示一個對象
* 1、類中的每一個枚舉成員都是該類的一個實例對象
* 2、構造函數私有化
* 3、提供操作枚舉成員的抽象方法和靜態方法
* @author 楊信
*
*/
public abstract class WeekDate {
/**
* 星期一
*/
public static final WeekDate MON = new WeekDate("MON",0) { //匿名子類
@Override
public WeekDate nextDay() {
return TUES;
}
@Override
public WeekDate preDay() {
return SUN;
}
@Override
public String toString() {
return "WeekDate.MON";
}
};
/**
* 星期二
*/
public static final WeekDate TUES = new WeekDate("TUES",1) {
@Override
public WeekDate nextDay() {
return WEDNES;
}
@Override
public WeekDate preDay() {
return MON;
}
@Override
public String toString() {
return "WeekDate.TUES";
}
};
/**
* 星期三
*/
public static final WeekDate WEDNES = new WeekDate("WEDNES",2) {
@Override
public WeekDate nextDay() {
return THURS;
}
@Override
public WeekDate preDay() {
return TUES;
}
@Override
public String toString() {
return "WeekDate.WEDNES";
}
};
/**
* 星期四
*/
public static final WeekDate THURS = new WeekDate("THURS",3) {
@Override
public WeekDate nextDay() {
return FRI;
}
@Override
public WeekDate preDay() {
return WEDNES;
}
@Override
public String toString() {
return "WeekDate.THURS";
}
};
/**
* 星期五
*/
public static final WeekDate FRI = new WeekDate("FRI",4){
@Override
public WeekDate nextDay() {
return SATUR;
}
@Override
public WeekDate preDay() {
return THURS;
}
@Override
public String toString() {
return "WeekDate.FRI";
}
};
/**
* 星期六
*/
public static final WeekDate SATUR = new WeekDate("SATUR",5){
@Override
public WeekDate nextDay() {
return SUN;
}
@Override
public WeekDate preDay() {
return FRI;
}
@Override
public String toString() {
return "WeekDate.SATUR";
}
};
/**
* 星期日
*/
public static final WeekDate SUN = new WeekDate("SUN",6){
@Override
public WeekDate nextDay() {
return MON;
}
@Override
public WeekDate preDay() {
return SATUR;
}
@Override
public String toString() {
return "WeekDate.SUN";
}
};
private static Map<String, WeekDate> valueMap = new HashMap<String, WeekDate>();
/**
* 枚舉名稱
*/
private final String name;
/**
* 枚舉成員的順序
*/
private final int ordinal;
private WeekDate(String name,int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
/**
* 保存枚舉成員
*/
private static WeekDate[] values = {
MON,TUES,WEDNES,THURS,FRI,SATUR,SUN
};
//初始化
static {
valueMap.put("MON", values[0]);
valueMap.put("TUES", values[1]);
valueMap.put("WEDNES", values[2]);
valueMap.put("THURS", values[3]);
valueMap.put("FRI", values[4]);
valueMap.put("SATUR", values[5]);
valueMap.put("SUN", values[6]);
}
/**
* 下一天
* @return
*/
public abstract WeekDate nextDay();
/**
* 前一天
* @return
*/
public abstract WeekDate preDay();
/**
* 枚舉中的所有成員
* @return
*/
public static WeekDate[] values() {
return values;
}
/**
* 將一個字符串轉換成一個枚舉成員對象
* @param name 枚舉名稱
* @return 枚舉對象
*/
public static WeekDate valueOf(String name) {
if (name.equalsIgnoreCase("MON")) {
return MON;
} else if (name.equalsIgnoreCase("TUES")) {
return TUES;
} else if (name.equalsIgnoreCase("WEDES")) {
return WEDNES;
} else if (name.equalsIgnoreCase("THURS")) {
return THURS;
} else if (name.equalsIgnoreCase("FRI")) {
return FRI;
} else if (name.equalsIgnoreCase("SATUR")) {
return SATUR;
} else if (name.equalsIgnoreCase("SUN")) {
return SUN;
} else {
throw new IllegalArgumentException("找不到" + name + "枚舉類型!");
}
}
/**
* 優化字符串轉枚舉對象
* @param name 枚舉名稱
* @return 枚舉對象
*/
public static WeekDate valueOf_2(String name) {
WeekDate value = valueMap.get(name.toUpperCase());
if (value == null) {
throw new IllegalArgumentException("找不到" + name + "枚舉類型!");
}
return value;
}
public String getName() {
return name;
}
public int getOrdinal() {
return ordinal;
}
/**
* 下一天
* @return
*/
/*public String nextDay() {
if(this == MON) {
return "TUES";
} else if (this == TUES) {
return "WEDNES";
} else if (this == WEDNES) {
return "THURS";
} else if (this == THURS) {
return "FRI";
} else if (this == FRI) {
return "SATUR";
} else if (this == SATUR) {
return "SUN";
} else {
return "MON";
}
}*/
/**
* 前一天
*/
/*public String preDay() {
if (this == MON) {
//....
} else if (...)....
}*/
}
2、使用JDK5.0中提供的枚舉特性改善普通類模擬枚舉的功能
/**
* 枚舉的應用
* 存儲每周中的天份
*/
public enum WeekDateEnum {
MON {
@Override
public WeekDateEnum nextDay() {
return TUES;
}
@Override
public WeekDateEnum preDay() {
return SUN;
}
}, TUES {
@Override
public WeekDateEnum nextDay() {
return WEDNES;
}
@Override
public WeekDateEnum preDay() {
return MON;
}
}, WEDNES {
@Override
public WeekDateEnum nextDay() {
return THURS;
}
@Override
public WeekDateEnum preDay() {
return TUES;
}
}, THURS {
@Override
public WeekDateEnum nextDay() {
return FRI;
}
@Override
public WeekDateEnum preDay() {
return WEDNES;
}
}, FRI {
@Override
public WeekDateEnum nextDay() {
return SATUR;
}
@Override
public WeekDateEnum preDay() {
return THURS;
}
}, SATUR {
@Override
public WeekDateEnum nextDay() {
return SATUR;
}
@Override
public WeekDateEnum preDay() {
return FRI;
}
}, SUN {
@Override
public WeekDateEnum nextDay() {
return SATUR;
}
@Override
public WeekDateEnum preDay() {
return MON;
}
};
private WeekDateEnum() {}
/**
* 下一天
* @return
*/
public abstract WeekDateEnum nextDay();
/**
* 前一天
* @return
*/
public abstract WeekDateEnum preDay();
/**
* 枚舉對象公共的toString方法,可以在case塊中反饋自己想要返回的信息
*/
public String toString() {
switch (this) {
case MON:
return "WeekDateEnum.MON";
case TUES:
return "WeekDateEnum.TUES";
case WEDNES:
return "WeekDateEnum.WEDNES";
case THURS:
return "WeekDateEnum.THURS";
case FRI:
return "WeekDateEnum.FRI";
case SATUR:
return "WeekDateEnum.SATUR";
case SUN:
return "WeekDateEnum.SUN";
default:
return null;
}
}
}
3、枚舉功能測試
/**
* 枚舉功能測試
*/
public class EnumTest {
public static void main(String[] args) {
//使用普通JAVA類模擬枚舉的應用
WeekDate weekDate = WeekDate.MON; //獲得一個枚舉對象
//調用枚舉中提供的方法
System.out.println(weekDate.nextDay());
System.out.println(weekDate.preDay());
System.out.println(weekDate.getName());
//獲得枚舉成員所在枚舉成員列表中的位置
System.out.println(weekDate.getOrdinal());
//調用某一個枚舉成員的方法
System.out.println(WeekDate.values()[0].preDay());
System.out.println("---------------遍曆枚舉成員,普通JAVA類模擬--------------------------");
for (WeekDate weekDate2 : WeekDate.values()) {
System.out.println(weekDate2);
}
System.out.println("\n=================================================================\n");
//使用JDK中提供的枚舉特性功能應用
WeekDateEnum weekDateEnum = WeekDateEnum.MON; //獲得一個枚舉對象
System.out.println(WeekDate.values().length); //獲得枚舉成員數量
System.out.println(weekDateEnum.name()); //獲得枚舉的字符串名稱
System.out.println(weekDateEnum.toString()); //打印枚舉對象,已重寫toString方法,默認打印枚舉的名稱
System.out.println(weekDateEnum.nextDay().ordinal()); //枚舉成員列表中的位置
System.out.println(WeekDateEnum.valueOf("FRI").nextDay().ordinal());
System.out.println("---------------遍曆枚舉成員,使用JDK的枚舉特性-------------------------");
for (WeekDateEnum enumDemo : WeekDateEnum.values()) {
System.out.println(enumDemo);
}
}
}
4、測試結果

最後更新:2017-04-02 06:52:21