gpt4 book ai didi

java - 如何在不冒失去对称属性的风险的情况下使用 hibernate 实现相等?

转载 作者:搜寻专家 更新时间:2023-10-30 21:09:51 24 4
gpt4 key购买 nike

在阅读(同样,很久以前就应该这样做)正确实现 equals 和 hashcode 之后,我得出了这些对我有用的结论:

如果是 JDK 7 之前的版本:首选使用 Apache commons equalsbuilder 和 hashcodebuilder。 (或 Guava )。他们的 javadoc 包含如何以良好方式使用它们的示例。

如果是 JDK 7++:使用新的 Objects 工具类

但是,如果为 hibernate 编写,则会出现一些特殊要求(请参阅下面的资源)其中推荐使用 instanceof 而不是 getClass,因为 hibernate 会创建延迟加载的子类代理。

但据我了解,如果这样做,则会出现另一个潜在问题:使用 getClass 的原因是为了确保 equals 契约的对称属性。 Java文档:

*It is symmetric: for any non-null reference values x and y, x.equals(y) 
should return true if and only if y.equals(x) returns true.*

并且通过使用 instanceof,可以不对称。示例:B 扩展了 A。A 的 equals 对 A 进行了 instanceof 检查。B 的 equals 对 B 进行了 instanceof 检查。给 A a 和 B b:

a.equals(b) --> 真b.equals(a) --> 假

如何在不冒丢失对称属性的风险的情况下使用 hibernate 实现 equals?好像用getClass不安全,用instanceof也不安全?

从不向子类添加重要成员,然后安全地使用 instanceof(对于 hibernate 而言)的答案是什么?

我阅读的资源:

What issues should be considered when overriding equals and hashCode in Java?

Josh Bloch 的优秀著作“Effective Java”中的第 7 项和第 8 项,http://web.archive.org/web/20110622072109/http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf

关于 Java 7:http://www.javacodegeeks.com/2012/11/guavas-objects-class-equals-hashcode-and-tostring.html

最佳答案

在进一步讨论之后,我将这个问题总结为:

  • 使用 instanceof,您永远无法向子类添加重要成员。(无法在保留等式契约的同时扩展可实例化类并添加值组件 (Bloch)
  • 使用 getClass 会违反 Liskov 替换原则

朗格斯说 http://www.angelikalanger.com/Articles/JavaSolutions/SecretsOfEquals/Equals.html

  • The instanceof test is correct only for final classes or if at least method equals() is final in a superclass. The latter essentially implies that no subclass must extend the superclass's state, but can only add functionality or fields that are irrelevant for the object's state and behavior, such as transient or static fields.

Implementations using the getClass() test on the other hand always comply to the equals() contract; they are correct and robust. They are, however, semantically very different from implementations that use the instanceof test. Implementations using getClass() do not allow comparison of sub- with superclass objects, not even when the subclass does not add any fields and would not even want to override equals() . Such a "trivial" class extension would for instance be the addition of a debug-print method in a subclass defined for exactly this "trivial" purpose. If the superclass prohibits mixed-type comparison via the getClass() check, then the trivial extension would not be comparable to its superclass. Whether or not this is a problem fully depends on the semantics of the class and the purpose of the extension.

总结 - 将 instanceof 与 final 一起用于 equals 可避免破坏对称性,并避免 hibernate “代理”问题。

链接

关于java - 如何在不冒失去对称属性的风险的情况下使用 hibernate 实现相等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14802422/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com