为什么 Java 不允许在 Enum 中重写 equals(Object) ?
我注意到以下代码片段...
@Override
public boolean equals(Object otherObject) {
...
}
...不允许用于枚举,因为方法 equals(Object x)
在 final href="http://download.oracle.com/javase/6/docs/api/java/lang/Enum.html#equals%28java.lang.Object%29" rel="noreferrer">Enum< /代码>
。为什么会这样呢?
我想不出任何需要覆盖 Enum 的 equals(Object) 的用例。我只是想知道这种行为背后的原因。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
除了
return this == other
之外的任何内容都将违反直觉,并且违反最小惊讶原则。当且仅当两个枚举常量是同一个对象时,它们才应相等
,并且覆盖此行为的能力很容易出错。同样的推理也适用于
hashCode()
、clone()
、compareTo(Object)
、name()
、<代码>ordinal()和getDeclaringClass()
。JLS 并不促使选择将其定为最终版本,而是在枚举上下文中提到 equals 此处。片段:
Anything but
return this == other
would be counter intuitive and violate the principle of least astonishment. Two enum constants are expected to beequal
if and only if they are the same object and the ability to override this behavior would be error prone.Same reasoning applies to
hashCode()
,clone()
,compareTo(Object)
,name()
,ordinal()
, andgetDeclaringClass()
.The JLS does not motivate the choice of making it final, but mentions equals in the context of enums here. Snippet:
对于
enum
的实例(值)相等意味着什么,已经提供了一个强烈直观的概念。允许重载 equals 方法会导致违反该概念,从而导致意外行为、错误等。There is already provides a strong intuitive notion of what it means for instances (values) of an
enum
to be equal. Allowing the overloading theequals
method would lead to that notion being violated, leading to unexpected behavior, bugs and so on.有时我们需要处理不符合Java命名标准的数据。如果能够做这样的事情那就太好了:
“String”类需要修改以适应......
Sometimes we need to deal with data that does not conform to Java naming standards. It would be nice to be able to do something like this:
The "String" class would need to be modified to accommodate...
我会采纳大多数人的意见。如果禁止覆盖 Enum::equals,我认为这并不是遵循最小惊讶原则。我认为是为了不破坏Java。
在 JVM 和一些旧的类(例如 EnumMap)中,Enum 标识可以在内部使用 int 进行编码。例如,如果我们允许重写 Enum::equals,则 EnumMap会破坏Map的契约。
I am going the majority opinion. If the override of Enum::equals is forbidden, I don't think it was to follow the principle of least astonishment. I think it is to not break Java.
In the JVM, and in some old classes such like EnumMap, Enum identities may be coded internally with an int. For example, if we allow to override Enum::equals, then EnumMap<K, V> would break the contract of Map.
正是因为 Java 设计者无法想到任何可想象的重写 Enum.equals(Object) 的用例,所以该方法被声明为 Final - 因此这种重写是不可能的。
It is precisely because the Java designers could not think of any conceivable use case for overriding Enum.equals(Object) that that method is declared as final - so that such overriding would be impossible.
我必须承认枚举是我最不想重写的 equals() 。
我认为 equals() 在枚举中是最终的原因是 Java 鼓励
==
用于枚举比较,而枚举中equals()
的实现只是使用它,因此允许equals()
被覆盖是为了防止>==
和equals()
的行为不同,这是其他开发人员不会想到的。I must confess enums are the last thing I would want to override
equals()
in.I think the reason
equals()
is final in enums is that Java encourages==
for enum comparison, and the implementation ofequals()
in enums simply uses it, So allowingequals()
from being overridden is to prevent==
andequals()
from behaving differently, which is something other developers would not expect.