高效Java技巧之不滥用枚举的下标

所有的枚举类型都有一个ordinal方法,将返回枚举值在枚举类中的位置。

1
2
3
4
5
6
// 滥用下标,将下标与枚举值的属性特征联系在一起,应当避免这样做
public enum Ensemble {
SOLO, DUET, TRIO, QUARTET, QUINTET,
SEXTET, SEPTET, OCTET, NONET, DECTET;
public int numberOfMusicians() { return ordinal() + 1; }
}

Ensemble这个枚举表示合奏,枚举值从独奏(SOLO)依次增加直到十重奏(DECTET),numberOfMusicians表示演奏的数目,正好是下标值加1。比如SOLO排在第一个,下标值为0,而演奏数目正好是1。这种方式非常取巧,但是可能给维护带来噩梦。如果给枚举值重新排序,numberOfMusicians方法的返回值就不再正确。如果有一个新的枚举值对应的演奏数目和已有的枚举值一样,比如double quartet(双重四重奏),和OCTET一样,也是8个演奏,就会造成问题。此外,如果有一个演奏数目与已有的并不连续,比如现在想在上面的枚举基础上加一个triple quartet(三重四重奏),由于演奏数目是12,要想增加这个枚举值,就得先加演奏数目为9、10、11的枚举值,而这本来很可能是完全不需要的。

永远不要将与枚举值有关的属性和它的下标相关联,而应该将属性值独立保存。

1
2
3
4
5
6
7
8
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; }
}

实际上,在枚举的定义中,对ordinal这个方法进行了明确说明:

1
大部分编程人员不会用到这个方法,它是被设计来用于基于枚举的数据结构:EnumSet和EnumMap。

所以,除非你在编写这样的数据结构,最好不好使用ordinal这个方法。

© 2018 谈谈IT All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero