美文网首页
ITEM 35: 使用实例变量而不是enum的内部顺序

ITEM 35: 使用实例变量而不是enum的内部顺序

作者: rabbittttt | 来源:发表于2019-07-26 18:17 被阅读0次

ITEM 35: USE INSTANCE FIELDS INSTEAD OF ORDINALS
  许多枚举自然地与一个 int 值关联。所有枚举都有一个序数方法,它返回每个枚举常量在其类型中的数值位置。您可能想从序数中派生一个关联的int值:

// Abuse of ordinal to derive an associated value - DON'T DO THIS
public enum Ensemble {
  SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET;
  public int numberOfMusicians() { return ordinal() + 1; } 
}

  虽然这个 enum 可以工作,但它的维护是一个噩梦。如果常量被重新排序,numberOfMusicians 方法将崩溃。如果您想添加第二个与您已经使用过的 int 值相关联的枚举常量,那就不太可能了。例如,为 double quartet 添加一个常量可能很好,它像 octet 一样,由八个音乐家组成,但是没有办法做到这一点。
  此外,如果不为所有中间的 int 值添加常量,就不能为 int 值添加常量。例如,假设您想添加一个表示 triple quartet (由12位音乐家组成)的常量。对于由11个音乐家组成的合奏没有标准术语,因此您必须为未使用的int值(11)添加一个虚拟常量。这样做是不优雅的。如果许多int values 未被使用,这是不切实际的。
  幸运的是,这些问题有一个简单的解决方案。永远不要从枚举的序号派生与枚举相关的值,而是将它存储在一个实例字段中:

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; }
}

  Enum规范对 ordinal 有这样的描述:“大多数程序员不需要使用这种方法。它是为基于枚举的通用数据结构(如 EnumSet 和 EnumMap)设计的。除非使用这个字符编写代码,否则最好完全避免使用序号方法。

相关文章

网友评论

      本文标题:ITEM 35: 使用实例变量而不是enum的内部顺序

      本文链接:https://www.haomeiwen.com/subject/ohndrctx.html