比较Java枚举成员:==或equals()?
我知道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()
的源代码,它只是按照==
。
然而,我使用==
,因为那将是无效的。
==
可以用于enum
?
是的:枚举具有严格的实例控件,允许您使用==
来比较实例。 这是语言规范提供的保证(我强调):
JLS 8.9枚举
一个枚举类型除了由枚举常量定义的枚举类型之外没有其他实例。
尝试显式实例化枚举类型是编译时错误。 Enum
的final clone
方法确保enum
常量永远不会被克隆,并且序列化机制的特殊处理可确保重复实例从不会因反序列化而被创建。 禁止枚举类型的反射实例化。 总而言之,这四件事确保enum
类型的实例不会超出enum
常量定义的实例。
因为只有一个每个实例enum
常数,允许使用==
操作者代替的equals
比较两个对象的引用时,如果已知它们中的至少一个是指方法enum
常数 。 ( Enum
的equals
方法是一个final
方法,它只是在其参数上调用super.equals
并返回结果,从而执行标识比较。)
这种保证足够强大,以至于Josh Bloch建议,如果你坚持使用单例模式,实现它的最好方法是使用单元素enum
(请参阅:Effective Java第2版,第3项:强制使用单例属性一个私有构造函数或一个枚举类型;也是Singleton中的线程安全)
==
和equals
什么区别?
作为提醒,需要说的是, ==
通常不是equals
的可行替代方案。 但是,如果是这样(比如enum
),则需要考虑两个重要区别:
==
从不抛出NullPointerException
enum Color { BLACK, WHITE };
Color nothing = null;
if (nothing == Color.BLACK); // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException
==
在编译时需要进行类型兼容性检查
enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };
if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK == Chiral.LEFT); // DOESN'T COMPILE!!! Incompatible types!
应该在适用时使用==
?
Bloch特别提到,具有对其实例的适当控制的不可变类可以保证其客户端==
可用。 enum
被具体提及来举例说明。
第1项:考虑静态工厂方法而不是构造函数
[...]它允许一个不可变类保证不存在两个相等的实例: a.equals(b)
当且仅当a==b
。 如果一个类做出这个保证,那么它的客户可以使用==
运算符而不是equals(Object)
方法,这可能会提高性能。 枚举类型提供了这种保证。
总而言之,在enum
上使用==
的参数是:
使用==
来比较两个枚举值,因为每个枚举常量只有一个对象。
在附注中,如果你写下如下的equals()
,实际上不需要使用==
来编写null安全代码:
public useEnums(SomeEnum a)
{
if(SomeEnum.SOME_ENUM_VALUE.equals(a))
{
...
}
...
}
这是一个最佳做法,称为比较左边的常数,你绝对应该遵循。
链接地址: http://www.djcxy.com/p/2673.html