枚举类完美解读

参考

   张孝祥系列教程

《thinking in java》- bruce eckel

场景
为什么需要枚举?从 程序中如何表示星期说起!
在实际开发中,当然可以在专门的常量类,比如说在Constants.java 中定义常量:public static final int MON = 1 , public static final int TUS = 2 等。但是这么做一点都不面向对象,也容易导致Constants.java类膨胀:系统中要定义常量的地方好多啊:业务异常码,响应字段等等。
分析
把上面的问题稍加抽象一下:我们需要这样一种数据结构 - 只取‘若干个’有限的含义明确的值(比如说,对于星期这样的业务就只能取 MON,TUS,,,SUN 等7个值),若取其他值则编译器最好就报错。在这种广泛存在的业务需求下,“枚举”类型诞生了!
实验
  • 普通类模拟枚举的实现

package cool.pengych.java.enumtest;
/**
 * Simulate the implementation of ENUM
 * fun: 普通类模拟枚举的实现
 * 1、私有化构造方法-保证实例个数为‘若干个’-有限
 *  2、定义所需要的类型常量
 *  3、定义常用方法
 * 
 * @author pengych.cool
 */
public class Weekend
{
	public static final Weekend  MON= new Weekend();
	
	public static final Weekend  TUS= new Weekend();
	
	private Weekend(){} // private constructor
	
	/**
	 * get the next day
	 * @return Weekend
	 */
	public Weekend next()
	{
		if(this.equals(MON)) //if判断,扩展性显然不高:下面会用模板设计模式加以优化
		{
			return TUS;
		}
			return MON;
	}
	
	public String toString()
	{
		return this.equals(MON) ? "MON" :"TUS";
	}
	
	public static void main(String[] args) 
	{
		System.out.print(WeekendNicer.MON.next());
    }
}

优化后的代码

package cool.pengych.java.enumtest;

/**
 *  optimize  the implementation of ENUM  with 
 *  利用模板方法设计模式优化Weekend.java类,使代码更加模块化,增强可扩展性
 * @author pengych.cool
 */
public abstract class WeekendNicer 
{
	public abstract  WeekendNicer next();
	
	private WeekendNicer(){}
	
	public static final WeekendNicer MON = new WeekendNicer()
	{
		public WeekendNicer next()
		{
			return TUS;
		}
	};
	
	public static final WeekendNicer TUS = new WeekendNicer()
	{
		public WeekendNicer next()
		{
			return MON;
		}
	};
	
	public String toString()
	{
		return this.equals(MON) ? "MON" :"TUS";
	}
}

  • 枚举的初体验与进阶实战

package cool.pengych.java.enumtest;

/**
 * 枚举类实战
 * 
 * @author pengych.cool
 */
public  class EnumTest
{
	
	public static void main(String[] args) 
	{
		Weekend weekend = Weekend.MON;
		System.out.println(weekend);
		
		WeekendE  weekende = WeekendE.MON;
		System.out.println(weekende.name());
		System.out.println(weekende.ordinal());
		System.out.println(WeekendE.valueOf("SUN").toString());
		System.out.println(WeekendE.values().length);
	}
	
	/**
	 *  base  enum : 枚举类基本使用
	 */
	public enum WeekendE 
	{
		MON(2),TUS,THI,FRI,WES,SAT,SUN;
		
		private WeekendE(){System.out.println("constructor with no argument!");}
		
		private WeekendE(int day){System.out.println("constructor with argument!");}
	}
	/**
	 * enhance enum : 枚举类进阶
	*/
	public enum TrafficLamp
	{
		RED(10) // 匿名内部类(调用父类的带参构造方法)
		{
			 public TrafficLamp nextLamp()
			{
				return YELLOW;
			}
		},
		YELLOW()
		{
			public TrafficLamp nextLamp()
			{
				return RED;
			}
		},
		GREEN(45)
		{
			public TrafficLamp nextLamp()
			{
				return YELLOW;
			}
		};	
		private int time;
		private TrafficLamp(){}
		private TrafficLamp(int time)
		{
			this.time = time;
		}
		public abstract TrafficLamp nextLamp();
	}
}

  • 单常量枚举简化单例模式的实现
package cool.pengych.java.enumtest;

/**
 * 由枚举类的实现原理可知,枚举类中若只有一个枚举常量,则该常量就是这个枚举类的唯一实例
 * @author pengych.cool
 *
 */
public enum EnumSingleton
{
	LOG;
	
	public void error(String log)
	{
		System.out.println(log);
	}
	public void debug(String log)
	{
		System.out.println(log);
	}
	public static void main(String[] args)
    {
		LOG.debug("test enum sigleton ");
		LOG.error("test enum sigleton ");
	}
}
总结

在实际项目中,遇到类型有限的业务性强的数据表示,优先考虑枚举类。

你可能感兴趣的:(枚举类完美解读)