Effective Java读书笔记九(Java Tips.Day.9)

TIP30 用enum代替int常量

也许我们常常会写以下类似的代码:

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

这种方法称为int枚举模式,它们在类型安全和使用方便性方面都有缺陷。
或者,这样的代码:

    public static final String ORANGE_SIHUI = "SIHUIJU";

同样是不被推荐使用的。

从java 1.5版开始,推荐使用enum代替这些垃圾代码:

    public enum Apple{FUJI,PIPPIN,GRANNY_SMITH}
    public enum ORANGE{NAVEL,TEMPLE,BLOOD}

枚举类的本质: 通过公有的静态 final域为每个枚举常量导出实例的类。
特点:没有构造器,所以客户端既不能创建枚举类的实例,也不能对枚举类扩展。换句话说,它们是实例受控的。


枚举类型具有类的一些特性,比如定义构造方法,定义域和方法。
还可以在枚举类声明abstract方法,然后在声明枚举常量时实现这个方法。
比如下面是一个实现加减乘除运算的枚举类:

    public enum Operation{
        PLUS{
            @Override
            double apply(double x,double y){
                return x+y;
            }
        },
        MINUS{
            @Override
            double apply(double x, double y) {
                return x-y;
            }
        },
        TIMES{
            @Override
            double apply(double x, double y) {
                return x*y;
            }
        },
        DIVIDES{
            @Override
            double apply(double x, double y) {
                return x / y;
            }
        };

        abstract double apply(double x,double y);
    }

再提醒一下,覆盖toString()会非常有用,在上述例子中,可以方便的打印算术式。

另外,枚举类型自带toValue()方法,它将常量的名字转变为常量本身。

总之,每当你需要一组固定常量的时候,就应当使用枚举,包括天然的枚举类型,比如行星,一周的天数、棋子的数目等等,或者菜单的选项、操作代码、命令行标记等等。如果多个枚举常量同时共享相同的行为,则考虑策略枚举。


TIP31 用实例域代替序数

有些枚举天生就与一个单独的int值相关联:

    public enum  Ensemble{
        /**
         * solo,二重奏,三重奏,四重奏.....
         */
        SOLO,DUET,TRIO,QUARTET,QUINTET,SEXET,SEPET,OCTET,NONET,DECTET;
        public int numberOfMusicians(){
            return ordinal()+1;
        }
    }

numberOfMusicians方法返回每个枚举常量在类型中的数字位置,而且同时表示该类型由几位音乐家演奏。

比如,SOLO调用该方法返回1,表示该类型是由1位音乐家演奏。

虽然它可以正常工作,但是常量如果进行重新排序,numberOfMusicians方法将返回错误的数字,要想维护这个方法将会非常复杂。


正确的方法是将该int值保存在实例域中:

    public enum  Ensemble{
        /**
         * solo,二重奏,三重奏,四重奏.....
         */


      SOLO(1),DUET(2),TRIO(3),QUARTET(4),
      QUINTET(5),SEXET(6),SEPET(7),OCTET(8), 
      NONET(9),DECTET(10);

        Ensemble(int size){
            this.numberOfMusicians = size;
        }
        private final int numberOfMusicians;


        public int numberOfMusicians(){
            return numberOfMusicians;
        }
    }

基本上你用不上ordinary()这个方法,它是设计成用于像EnumSet和EnumMap这种基于枚举的通用数据结构的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值