用enum代替int常量

枚举类型是指由一组固定的常量组成合法值的类型。例如一年中的季节,太阳系中的行星或者一副牌中的花色。在编程语言中还没有引入枚举类型之前,表示枚举类型的常用模式是声明一组具名的int常量,每个类型成员一个常量:

public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;
public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOD = 2;

这种方法称作int 枚举模式,存在着诸多不足。它在类型安全性和使用方便性方面没有任何帮助。如果你将apple传到想要orange的方法中,编译器也不会出现警告,还会用==操作符将apple与orange进行对比,甚至更糟糕。


JAVA枚举背后的基本想法非常简单:它们是通过公有的静态final域为枚举常量导出实例的类。因为没有可以访问的构造器,枚举类型是真正的final。因为客户端既不能创建枚举常量导出的类。因为没有可以访问的构造器,枚举类型是真正的final 。因为客户端既不能创建枚举类型的实例,也不能对它进行扩展,因此很可能 没有实例,而只有声明过的枚举常量。换句话说,枚举类型是实例受控的。它们是单例的泛型化,本质上是单元素的枚举。

public enum PayrollDay {
	MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY), WEDNESDAY(
			PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY), FRIDAY(PayType.WEEKDAY), SATURDAY(
			PayType.WEEKEND), SUNDAY(PayType.WEEKEND);
	private final PayType payType;

	PayrollDay(PayType payType) {
		this.payType = payType;
	}
	
	double pay(double hoursWorked, double payRate) {
		return payType.pay(hoursWorked, payRate);
	}

	private enum PayType {
		WEEKDAY {
			double overtimePay(double hours, double payRate) {
				return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT)
						* payRate / 2;
			}
		},
		WEEKEND {
			double overtimePay(double hours, double payRate) {
				return hours * payRate / 2;
			}
		};
		private static final int HOURS_PER_SHIFT = 8;

		abstract double overtimePay(double hours, double payRate);

		double pay(double hoursWorked, double payRate) {
			double basePay = hoursWorked * payRate;
			return basePay + overtimePay(hoursWorked, payRate);
		}
	}
}

总之:与int常量相比,枚举的类型优势是不言而喻的。枚举要易读得多,也更加安全,功能更加强大。许多枚举都不需要显式的构造器或者成员,但许多其它枚举则受益于“每个常量与属性的关联”以及“提供行为受这个属性影响的方法”。只有极少数的枚举受益于将多种行为与单个方法关联。在这种相对少见的情况下,特定于常量的方法要优先于启用自有值的枚举。如果多个枚举常量同时享有相同的行为,则考虑策略枚举。

摘自:effective java

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