2010-02-09 114 views
20

我正在看一些由公司其他部分维护的Java代码,顺便说一下一些前C和C++开发人员。有一两件事,是无处不在的是使用静态整型常量,比如Java枚举与静态常量

class Engine { 
    private static int ENGINE_IDLE = 0; 
    private static int ENGINE_COLLECTING = 1; 
    ... 
} 

除了缺少的“最终”预选赛,我有点被这种代码困扰。我本来希望看到的,主要是来自学校的Java培训,会更像

class Engine { 
    private enum State { Idle, Collecting }; 
    ... 
} 

但是,这些论据让我失望。如果有的话,为什么后者比前者好?

+4

用于使常数为'final'的+1。 – uckelman 2010-02-09 13:49:29

回答

24

为什么如果说毕竟是后者比前者更好 ?

它更好,因为它给你类型安全和自我记录。使用整型常量,您必须查看API文档以找出哪些值是有效的,并且没有任何东西阻止您使用无效值(或者更糟糕的是,完全不相关的整数常量)。使用枚举,方法签名直接告诉你什么值是有效的(IDE自动完成将起作用),并且不可能使用无效值。

的“整型常量枚举”模式是不幸的是很常见的,即使是在Java标准API(并从那里广泛效仿),因为Java没有枚举前的Java 5

+3

+1,因为你是唯一一个提到自我文档的人,如果你有一个方法,接受(或返回)一个代表一些代码的int,那么没有doc或者source就没有机会得出int的语义。但枚举有一个名称为每个值和签名是直接(通过类型)连接到枚举。 – Mnementh 2010-02-09 13:33:52

+1

+1“self-documenting”和“IDE autocompletion will work” – 2010-02-09 14:12:14

0

前者在1.5以前开始的代码中很常见。实际上,另一个常见的习惯用法是在界面中定义常量,因为它们没有任何代码。

+0

但是这种做法也鼓励使用继承这些常量,这有点难看。 :( – 2010-02-09 13:28:36

+0

@大卫:这是最少的问题,“整型常量枚举”原因 – 2010-02-09 13:29:51

+0

@迈克尔:但问题没有少 – 2010-02-09 13:31:26

5

通过使用int来引用一个常量,你不会强迫某人实际使用该常量。因此,举例来说,你可能有这需要发动机状态的方法,对此有人会乐意与调用:

engine.updateState(1); 

使用的enum用户坚持使用说明标签,所以它更清晰可辨。

1

有当静态的情况constance是首选的(而不是代码是具有大量依赖性的遗留代码),那就是当该值的成员不是/可能以后不是有限的。

想象一下,如果您以后可能会添加新的状态,如Collected。使用枚举的唯一方法是编辑原始代码,如果在已经有很多代码操作的情况下完成修改,则代码可能会出现问题。除此之外,我个人认为没有理由不使用枚举。

只是我的想法。

+0

但是,添加新状态可能需要代码中的其他更改(意味着处理新状态)。所以情况不太可能。遗留代码可能是此方法适用的唯一地方。 – Lajcik 2010-02-09 13:38:45

1
  1. Readabiliy - 当您使用枚举和做State.Idle,读者立即知道你正在谈论一个闲置状态。将此与4或5进行比较。

  2. 类型安全 - 当使用枚举,甚至误,用户无法通过一个错误的值,因为编译器将迫使他使用在枚举预申报值之一。如果是简单整数,他甚至可以通过-3274。

  3. 可维护性 - 如果你想添加一个新的状态Waiting,那么这将是很容易通过增加您的枚举状态恒定的等待没有任何casuing混乱添加新的状态。
8

从官方文档的摘录,http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

这个模式有很多问题,比如:

  • 没有类型安全 - 因为一个赛季只是一个int你可以通过在任何其他需要季节的int值,或者添加两个季节(这没有意义)。
  • 没有命名空间 - 你必须前缀一个int枚举的常量用于字符串(在这种情况下SEASON_),以避免与其他INT枚举类型的碰撞。
  • 脆性 - 因为int枚举是编译时常量,所以它们被编译到使用它们的客户机中。如果在两个现有常量之间添加新的常量或更改了顺序,则必须重新编译客户端。如果他们不是,他们仍然会跑,但他们的行为将是不确定的。
  • 打印的值是无信息的 - 因为他们只是整数,如果打印一出所有你得到的是一个数字,它不能告诉你它代表什么,甚至它是什么类型。

而这只是涵盖它。一个单词的论点是,枚举更具可读性和信息性。

还有一件事是枚举,就像类一样。可以有字段和方法。这使您可以选择包含有关枚举本身中每种类型状态的其他信息。

0

枚举还给你很大的灵活性。由于枚举本质上是类,所以可以用有用的方法来扩充它们(例如提供与枚举中的某个值相对应的国际化资源字符串,在枚举类型的实例和可能需要的其他表示之间来回转换等等。 )

1

从规范,这Lajcik报价的原因,进行了更详细的乔希布洛赫的有效的Java解释说,第30项。如果你有机会获得这本书,我建议你仔细阅读它。 Java Enums是完整的类,这就是为什么你需要编译时类型安全。你也可以给他们行为,给你更好的封装。