对象javadocs和Josh Bloch告诉我们应该如何实现hashCode / equals,好的IDE将正确处理各种类型的字段。关于所有问题的一些讨论是here。
这个问题是关于下一步:你如何确保他们保持良好?
特别是,我觉得对于大多数类来说,equals / hashCode应该像Bloch建议的那样实现(以及Eclipse和其他IDE的实现),并考虑到该类中所有非派生的业务逻辑字段。在将新字段添加到类中作为继续工作的一部分时,人们常常忘记将它们添加到equals / hashCode实现中。当两个对象看起来相等时,这可能导致难以发现的错误,但实际上不同于最近引入的字段的值。
如果成员字段发生变化,团队(甚至一个团队!)如何帮助确保类中的equals / hashCode继续考虑所有相关字段?
我知道Apache的EqualsBuilder和HashCodeBuilder可以使用反射,这显然会考虑正确的字段,但我想避免使用它们的性能成本。是否有其他方法来标记未包含在equals / hashCode中的字段,应该是什么?静态代码分析,IDE功能,单元测试技术?
答案 0 :(得分:8)
从未尝试过,但http://code.google.com/p/equalsverifier/怎么样?
答案 1 :(得分:7)
似乎在this question中提供了一个可能的答案。
我没有多关注Project Lombok,但我立即想到,嗯注释可以用于代码生成器。
答案 2 :(得分:1)
如何为每个要保护的课程编写单元测试。 单元测试
答案 3 :(得分:0)
您不需要在哈希码方法中包含每个字段。如果您在哈希码算法中使用了多个字段,则它可能会保持良好状态。我见过的IDE生成的算法使用随机(在实现时,而不是在执行时)的素数常量值,所以只需确保可能最终在同一个映射或树中的类(例如,它们实现相同的) interface)具有不同的常量值。当然,除非你想在接口级别上保持相等。
我从来没有见过哈希码算法“变坏” - 你担心这个问题不成比例。
答案 4 :(得分:0)
听起来你正在寻找的是IDE中的插件或功能,它执行类的分析并在equals()和hashCode()方法不引用所有相关字段时生成警告。
这基本上会将反射开销转移到IDE,而不是让它在运行时有成本。
不幸的是,我不知道有任何插件会这样做,不过我肯定会看看。
另一方面,这样的自动化工具如何知道哪些字段与业务逻辑相关?你可能需要用类似注释的东西来标记不相关的字段,否则你会发现自己有一些你无法摆脱的警告,但你知道这些警告是不正确的。
编辑:这个答案没用,所以我只是在这里从更好的答案中汇总真正有用的建议:
equals()
,hashCode()
和其他样板代码 - 因为它是在编译时生成的,任何更改该类将自动更新这些方法equals()
进行单元测试的方法 - 不支持测试hashCode()
答案 5 :(得分:0)
您可以使用使用反射(例如XStream)查找属性的工具将对象序列化为字符串,并将该字符串存储在存储库中。您的单元测试可以重新序列化对象并将结果与存储的值进行比较。
作为您自己的过程的一部分,使这些字符串的存储依赖于手动验证您的hashCode和equals正确捕获所有相关值。