第三十一条 用实例域代替序数

枚举中有个方法, ordinal()方法,它的值是枚举常量在类型中的数字位置,如果把枚举里面的内容对象看成是一个数组,那么,这个值就是索引。

public enum Ensemble {
    SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET;

    public int numberOfMusicians() {
        return ordinal() + 1;
    }
}

比如,int index = Ensemble.SOLO.ordinal(); 由于 SOLO 是枚举中的第一个值, 所以 index 的值为 0, numberOfMusicians() 方法意思是在索引的基础上,又加了1。这样写有个坏处就是每个枚举类型对应的值不固定,如果在SOLO 之前再插入一个新的类型,那么所有的枚举对象的 numberOfMusicians() 方法返回的值就都变了,如果以此为准做一些逻辑操作,需要用到索引值,则编译 正确,运行正确,但逻辑结果却不正确,并且还不好排查原因。枚举本身也想到了这一点,给出解决方案,就是增加一个属性值

public enum Ensemble {
    SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5), SEXTET(6), SEPTET(7), OCTET(8),
    DOUBLE_QUARTET(8), NONET(9), DECTET(10), TRIPLE_QUARTET(12);

    private final int numberOfMusicians;

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

    public int numberOfMusicians() {
        return numberOfMusicians;
    }
}

这样,每一个枚举都有一个自己的值,再怎么修改,都不会彼此影响其它对象,所以比较好用。所以还是用域值代替序数。


有一种情况可以直接使用序数,可以不用添加域值,写起来也简单。 代码中一般都会用到网络,那么我们会写一些网络地址,也会定义一些常量来映射地址,通常会把这些常量通过某种关系写在一块,这样就很容易知道项目中用了哪些接口,调用网络接口,现在的网络框架一般都会给每个不同的接口标注一个唯一的值,作为拿到报文后数据,刷新UI界面使用,刷新界面的逻辑要和数据接口对应的上,这是后,我们可以把接口的名字统一用一个枚举来标识,唯一值就用ordinal()方法获取,这时候里面随意修改位置都没关系,因为我们只需要它们的值不同,都是唯一的就可以了。满足类似这种情况的,我们可以用序数,否则还是要用实例域。


 

你可能感兴趣的:(java,effective,注解)