为什么我们不允许我们在Java中的Enum中覆盖哈希码
我目前只知道,Java中没有ENUM的HashCode()实现。它返回的只是super.hashcode(),而其他不变类(例如字符串)都有自己的HashCode()实现。当跨不同的JVM使用时,这会使枚举不安全。我认为Ordinal()非常适合计算ENUM的hashCode(),但是枚举中的HashCode()定义为最终,我不能覆盖它。我唯一能想到的解决方案是为枚举创建一个全新的Simalar。有建议吗?
我想取得这样的目标:
enum Fruit {
APPLE, POMEGRANATE, KIWI;
@override
public int hashCode() {
return Objects.hash(super.ordinal());
}
@override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
}
Fruit other = (Fruit)obj;
return super.ordinal() == other.ordinal();
}
}
有什么解决方案吗?或者 我想了解为什么此解决方案不好,因此在Java中不允许。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你说:
您可以在任何对象上都依靠
hashcode 在jvms上保持一致的
hashcode
,例如commented by shmosel.对象## HashCode
明确表示您不能依靠hashcode
在JVM的调用之间相同。引用Javadoc:你说:
否,我认为不是。您可以在应用程序版本之间定义枚举元素的顺序。您甚至可以添加或删除元素。因此,我们通常不应该依靠应用程序版本之间的序数。
你说:
我相信您在那里遇到麻烦。
你说:
是的。分配密钥。
如果要识别由
enum
子类的对象表示的实体的值,我建议您将成员字段添加到枚举类中,以唯一地识别每个实例。自然关键
您分配的价值取决于您的问题域。在特定行业或公司中,可能会有已知的标识符。例如,在处理水果时,也许可以分配拉丁科学植物名称。
在关系数据库理论中,其名称是天然键。
用法:
运行时。
请参阅此 code在indeone.com 中实时运行。
代理密钥(任意标识符)
如果您的业务领域中没有此类标识符,则分配任意永久标识符。
如果您不知道一个,请使用普遍唯一的识别符(UUID)。请参阅 uuid 类。
在关系数据库理论中,我们称之为A 替代键。
用法:
运行时。
顺便说一句,从技术上讲,“没有实现
hashcode()
enum
>”。继承的实现是其实现。该观点是 oop 。You said:
You can never rely on
hashCode
on any object to be consistent across JVMs, as commented by shmosel.The contract promised by
Object##hashCode
says explicitly that you cannot rely onhashCode
being the same between invocations of a JVM. To quote the Javadoc:You said:
No, I think not. You can define the order of elements of an enum between releases of your app. You can even add or delete elements. So we should generally not rely upon ordinal number between versions of an app.
You said:
I believe you are headed for trouble there.
You said:
Yes. Assign a key.
If you want to identify the value of the entities represented by your
Enum
subclass’ objects, I suggest you add a member field to your enum class to identify each instance uniquely.Natural key
What value you assign depends on your problem domain. In a particular industry or company, there may be a known identifier. For example, in handling fruits, perhaps a Latin scientific botanical name could be assigned.
In relational database theory, the name for this is a natural key.
Usage:
When run.
See this code run live at Ideone.com.
Surrogate key (arbitrary identifier)
If no such identifier exists in your business domain, then assign an arbitrary permanent identifier.
If you have no idea of one, then use a universally unique identifier (UUID). See the
UUID
class.In relational database theory, we call this a surrogate key.
Usage:
When run.
By the way, it is technically incorrect to say “there is no implementation of
hashCode()
ofEnum
”. The inherited implementation is its implementation. This perspective is fundamental to OOP.