From 3ece35d6e82cc3981eeacfca4426a558aad6b054 Mon Sep 17 00:00:00 2001 From: sjsdfg <736777445@qq.com> Date: Sat, 24 Nov 2018 15:06:35 +0800 Subject: [PATCH] =?UTF-8?q?35.=20=E4=BD=BF=E7=94=A8=E5=AE=9E=E4=BE=8B?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E6=9B=BF=E4=BB=A3=E5=BA=8F=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 35. 使用实例属性替代序数.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 35. 使用实例属性替代序数.md diff --git a/35. 使用实例属性替代序数.md b/35. 使用实例属性替代序数.md new file mode 100644 index 0000000..032df0e --- /dev/null +++ b/35. 使用实例属性替代序数.md @@ -0,0 +1,37 @@ +# 35. 使用实例属性替代序数 + +  许多枚举通常与单个 `int` 值关联。所有枚举都有一个 `ordinal` 方法,它返回每个枚举常量类型的数值位置。你可能想从序数中派生一个关联的 `int` 值: + +```Java +// 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; } +} +``` + +  虽然这个枚举能正常工作,但对于维护来说则是一场噩梦。如果常量被重新排序,`numberOfMusicians` 方法将会中断。 如果你想添加一个与你已经使用的 `int` 值相关的第二个枚举常量,则没有那么好运了。 例如,为双四重奏(double quartet)添加一个常量可能会很好,它就像八重奏一样,由 8 位演奏家组成,但是没有办法做到这一点。 + +  此外,如果没有给所有这些 `int` 值添加常量,也不能为某个 `int` 值添加一个常量。例如,假设你想要添加一个常量,表示一个由 12 位演奏家组成的三重四重奏(triple quartet)。对于由 11 个演奏家组成的合奏曲,并没有标准的术语,因此你不得不为未使用的 `int` 值(11)添加一个虚拟常量(dummy constant)。最多看起来就是有些不好看。如果许多 `int` 值是未使用的,则是不切实际的。 + +  幸运的是,这些问题有一个简单的解决方案。 **永远不要从枚举的序号中得出与它相关的值; 请将其保存在实例属性中:** + +```Java +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` 方法说道:“大多数程序员对这种方法没有用处。 它被设计用于基于枚举的通用数据结构,如 `EnumSet` 和 `EnumMap`。“除非你在编写这样数据结构的代码,否则最好避免使用 `ordinal` 方法。 + + +