第六章:枚举和注解

java支持两种特殊用途的引用类型:1、类,枚举类型(enum type);2、接口,注解类型(annotation type)。

第34条:用enum代替int常量

如:

public enum Planet{
    MERCURY    (3.302e+23,2.439e6),
    VENUS    (4.869e+24,6.052e6),
    ......
    EARTH    (5.945e+24,6.378e6);
    
    private final double mass;                //In kilograms
    private final double radius;            //In meters;
    private final double surfaceGravity;    //In m / s^2;
    private static final double G = 6.67300E-11;
    // Constructor
    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(double mass){
        return mass * surfaceGravity;    //F = ma;
    }
}

1、枚举的功能非常强大。如:打印上面枚举全部行星数据

public class WeightTable{
    public static void main(String args){
        double earthWight = Double.PasrseDouble(args[0]);
        double mass = earthWeight / Planet.EARTH.surfaceGiavity();
        for (Planet p : Planet.values()){
            System.out.printf("Weight on %s is %f%n",p,p.surfaceWeigth(mass));
        }
    }
}

2、枚举类型具有一个静态的values方法。

3、枚举是安全,对于被删除元素,如果重新编译客户端代码,在引用这个元素的一行会出现一条错误。如果没有重新编译客户端代码,在运行时会在这一行抛出一个异常。

4、枚举类型和不同的行为关联起来

public enum Operation{
    PLUS("+")    {public double apply(double x,double y){ return x + y; }},
    MINUS("-")    {public double apply(double x,double y){ return x - y; }},
    TIMES("*")    {public double apply(double x,double y){ return x * y; }},
    DIVIDE("/")    {public double apply(double x,double y){ return x / y; }};
    
    private finale String symbol;    
    operation(String symbol)    { this.symbol = symbol;}
    public abstract double apply(double x,double y);
}

5、枚举中的switch语句适合于外部的枚举类型增加特定于常量的行为

enum PayrollDay{
    MONDAY,TUESDAY,WEDESDAY,THURSDAY,FRIDAY,
    SATURDAY(PayType.WEKEND),SUNDAY(PayType.WEKEND);
    
    private final PayType payType;
    
    PayrollDay(PayType payType)    { this.payType = payType ;}
    PayrollDay()    { this(PayType.WEKDAY);}    //Default
    
    int pay(int minutesWorked,int payRate){
        return payType.pay(minutesWorked,payRate);
    }
    
    //The strategy enum type
    private enum Paytype{
        WEEKDAY{
            int overtimePay(int minsWorked,int payRate){
                return minsWorked <= MINS_PER_SHIFT ? 0 : (minsWorked - MINS_PER_SHIFT) * payRate / 2;
            }
        },
        WEEKEND{
            int overtimePay(int minsWorked,int payRate){
                return minsWorked * payRate / 2;
            }
        };
        
        
        abstract int overtimePay(int mins,int payRate);
        private static final int MINS_PER_SHIFT = 8 * 60;
        
        int pay (int minsWorked,int payRate){
            int basePay + overtimePay(minsWorked,payRate);
        }
    }
}

总结:枚举:可读性好、安全、功能强大。


一个好奇的人