zoukankan      html  css  js  c++  java
  • Java枚举(用Java普通类模拟枚举的实现原理及JDK枚举API使用示例)

    枚举的特点:

    ◆类型安全(Type Safety) 
    ◆紧凑有效的枚举数值定义(Compact, Efficient Declaration of Enumerated Values) 
    ◆无缝的和程序其它部分的交互操作(Seamless integration with other language features) 
    ◆运行的高效率(Runtime efficiency)

    详情请看:http://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、测试结果


  • 相关阅读:
    使用过Redis,我竟然还不知道Rdb
    系统的讲解
    系统的讲解
    我眼中的 RPC
    Swoole Timer 的应用
    场景调研
    二维数组环求最大子数组
    《你的灯亮着吗》 阅读笔记三
    《你的灯亮着吗》 阅读笔记二
    《你的灯亮着吗》阅读笔记一
  • 原文地址:https://www.cnblogs.com/xyang0917/p/4172549.html
Copyright © 2011-2022 走看看