我知道Java枚举被编译为具备私有构造函数和一堆公共静态成员的类。 比较给定枚举的两个成员时,我老是使用.equals()
,例如 程序员
public useEnums(SomeEnum a) { if(a.equals(SomeEnum.SOME_ENUM_VALUE)) { ... } ... }
可是,我遇到了一些使用equals运算符==
而不是.equals()的代码: 编程
public useEnums2(SomeEnum a) { if(a == SomeEnum.SOME_ENUM_VALUE) { ... } ... }
我应该使用哪一个运算符? 安全
正如其余人所说, ==
和.equals()
在大多数状况下都有效。 您没有比较其余人指出的彻底不一样类型的对象的编译时间肯定性是有效和有益的,可是比较两种不一样编译时间类型的对象的特殊类型的错误也能够经过FindBugs找到(而且可能经过Eclipse / IntelliJ编译时间检查),所以Java编译器发现它并无增长太多额外的安全性。 函数
然而: 性能
==
不会抛出NPE在我心目中是一个缺点 ==
。 几乎不须要enum
类型为null
,由于您可能但愿经过null
表示的任何额外状态均可以做为附加实例添加到enum
中。 若是它意外地为null
,那么我宁愿拥有一个NPE而不是==
默默地评估为false。 所以,我不一样意它在运行时的观点是更安全的 。 最好养成永远不要让enum
值为@Nullable
的习惯。 ==
更快的说法也是假的。 在大多数状况下,您将在编译时类型为enum类的变量上调用.equals()
,在这些状况下,编译器能够知道这与==
相同(由于enum
的equals()
方法能够(不会被覆盖)并能够优化函数调用。 我不肯定编译器当前是否这样作,可是若是没有这样作,结果证实这是Java总体的性能问题,那么我宁愿修复该编译器,也不肯让100,000个Java程序员更改其编程样式以适应特定编译器版本的性能特征。 enums
是对象。 对于全部其余对象类型,标准比较是.equals()
,而不是==
。 我认为对enums
进行例外处理是危险的,由于您可能最终会意外地将Object与==
而不是equals()
进行比较,尤为是当您将enum
重构为非枚举类时。 在这种重构的状况下,从上面的工做原理是错误的。 为了使本身确信==
的使用是正确的,您须要检查所讨论的值是enum
仍是基元。 若是它是一个非enum
类,那将是错误的,可是很容易遗漏,由于代码仍然能够编译。 使用.equals()
错误的惟一状况是所讨论的值是不是基元; 在这种状况下,代码将没法编译,所以更容易遗漏。 所以, .equals()
更容易被识别为正确的,而且对于未来的重构更安全。 我实际上认为Java语言应该在Objects上定义==,以在左侧值上调用.equals(),并为对象标识引入一个单独的运算符,但这不是Java的定义方式。 优化
总之,我仍然认为参数支持对enum
类型使用.equals()
。 spa
若是枚举是正确的,那么正确! .net
二者在技术上都是正确的。 若是您查看.equals()
的源代码,则它仅.equals()
==
。 code
我使用==
,可是这将是null安全的。 对象
使用==
比较两个枚举值是可行的,由于每一个枚举常量只有一个对象。
附带说明一下,若是您像这样编写equals()
,则实际上无需使用==
来编写空安全代码:
public useEnums(final SomeEnum a) { if (SomeEnum.SOME_ENUM_VALUE.equals(a)) { … } … }
这是被称为“ 从左边比较常量”的最佳实践,您绝对应该遵循。
我想补充多基因润滑剂的答案:
我我的更喜欢equals()。 可是它对类型兼容性进行检查。 我认为这是一个重要的限制。
要在编译时检查类型兼容性,请在枚举中声明并使用自定义函数。
public boolean isEquals(enumVariable) // compare constant from left public static boolean areEqual(enumVariable, enumVariable2) // compare two variable
这样,您将得到两种解决方案的所有优点:NPE保护,易于阅读的代码以及在编译时进行类型兼容性检查。
我还建议为枚举添加一个UNDEFINED值。