枚举和注解

30.用enum代替int类型

枚举类型指由一组固定的常量组成合法值的类型,没有枚举型前用的是声明一组常量。在安全和使用上没有帮助,将Apple传到orange也没有问题,还会用==比较,而且是编译器常量,如果改变,必须重新编译,不重新编译也没问题,行为就不确定了

	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 PRANGE_NAVEL = 0;
	public static final int ORANGE_TEMPLE = 1;
	public static final int ORANGE_BLOOD = 2;

这是int枚举模式

	public enum Apple{FUJI,PIPPIN,GRANNY_SMITH}
	public enum Orange{NAVEL,TEMPLE,BLOOD}
本质是int型,是通过公有的静态final域为每个枚举常量导出实例的类,没有可以访问的构造器,枚举类型是真正的final,是单例和泛型化的
public enum Planet {
//枚举常量后面括号中的数值就是传递给构造器的参数
	MERCURY(3.302e+23,2.439e6),
	VENUS(4.859e+24,2.439e6),
	EARTH(3.302e+23,2.439e6),
	MARS(3.302e+23,2.439e6),
	JUPITER(3.302e+23,2.439e6),
	SATUNE(3.302e+23,2.439e6),
	URANUS(3.302e+23,2.439e6),
	NEPTUNE(3.302e+23,2.439e6);
	private final double mass;
	private final double radius;
	private final double surfaceGravity;
	private static final double G = 6.67300E-11;
	Planet(double mass, double radius) {
		this.mass = mass;
		this.radius = radius;
		surfaceGravity = G *mass /(radius *radius);
	}
	public double mass(){
		return mass;
	}
	public double radius(){
		return radius;
	}
	public double surfaceGravity(){
		return surfaceGravity;
	}
	public double surfaceWeight(double mass){
		return mass *surfaceGravity;
	}
}
public class WeightTable {

	public static void main(String[] args) {
		double earthWeight = 1;
		double mass = earthWeight /Planet.EARTH.surfaceGravity();
		//静态的values方法,按照声明顺序返回值数组
		for (Planet planet : Planet.values()) {
			System.out.println(planet.surfaceWeight(mass));
		}
	}
}
//计算加减乘除,通过启用枚举的值来实现,代码脆弱,如果添加新的枚举值,switch里不添加相应的条件,试图用新的运算 ,会运行失败
public enum Operation {
	PLUS,MINUS,TIMES,DIVIDE;
	double apply(double x,double y){
		switch (this) {
		case PLUS:return x+y;
		case MINUS:return x-y;
		case TIMES:return x*y;
		case DIVIDE:return x/y;
		}
		throw new AssertionError();
	}
}
//将不同的行为与每个常量连接起来,在枚举类型中声明一个抽象方法,在常量的类主体中,用具体的方法覆盖每个常量的抽象apply方法
public enum Operation {
	PLUS{double apply(double x,double y){return x+y;}},
	MINUS{double apply(double x,double y){return x-y;}},
	TIMES{double apply(double x,double y){return x*y;}},
	DIVIDE{double apply(double x,double y){return x/y;}};
	abstract double apply(double x,double y);
}
public enum Operation {
	PLUS("+"){double apply(double x,double y){return x+y;}},
	MINUS("-"){double apply(double x,double y){return x-y;}},
	TIMES("*"){double apply(double x,double y){return x*y;}},
	DIVIDE("/"){double apply(double x,double y){return x/y;}};
	private final String symbol;
	private Operation(String symbol) {
		this.symbol=symbol;
	}
	//覆盖toString方法返回与该操作相关联的符号
	@Override
	public String toString(){
		return symbol;
	}
	abstract double apply(double x,double y);
}
//常量被创建后,Operation常量从静态代码块中被放入到stringToEnum的map中
	private static final Map<String, Operation> stringToEnum = new HashMap<>();
	static{
		for (Operation op:values()) {
			stringToEnum.put(op.toString(), op);
		}
	}
	//将定制的字符串表示法变回相应的枚举
	public static Operation fromString(String symbol){
		return stringToEnum.get(symbol);
	}
每添加一个枚举常量,强制选择一种策略,策略枚举

//将加班工资计算移到一个私有的嵌套枚举中
enum PayrollDay {

	MONDAY(PayType.WEEKDAY),
	TUESDAY(PayType.WEEKDAY),
	WENESDAY(PayType.WEEKDAY),
	THURSDAY(PayType.WEEKDAY),
	FRIDAY(PayType.WEEKDAY),
	SATURDAY(PayType.WEEKEND),
	SUNDAY(PayType.WEEKEND);
	private final PayType payType;
	PayrollDay(PayType payType) {
		this.payType =payType;
	}
	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);
		}
	}
}
枚举中的switch语句适合于给外部的枚举类型增加特定于常量的行为。
//假设Operation枚举不受自己的控制,希望它有个实例方法来返回每个运算的反运算
	public static Operation inverse(Operation op){
		switch (op) {
		case PLUS:return Operation.MINUS;
		case MINUS:return Operation.PLUS;
		case TIMES:return Operation.DIVIDE;
		case DIVIDE:return Operation.MINUS;
		default:throw new AssertionError(op);
	}
每当需要一组固定常量的时候使用枚举,包括在编译时就知道的所有可能值的其他集合
31.用实例域代替序数




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值