带有继承的@Data注释lombok上的警告等于/哈希码

Posted

技术标签:

【中文标题】带有继承的@Data注释lombok上的警告等于/哈希码【英文标题】:Warning equals/hashCode on @Data annotation lombok with inheritance 【发布时间】:2016-11-29 01:54:54 【问题描述】:

我有一个继承自其他实体的实体。另一方面,我正在使用 lombok 项目来减少样板代码,所以我放了@Data 注释。带有继承的注释@Data 会产生下一个警告:

生成 equals/hashCode 实现但不调用超类,即使该类没有扩展 java.lang.Object。如果这是故意的,请将@EqualsAndHashCode(callSuper=false) 添加到您的类型中。

是否建议添加注解@EqualsAndHashCode (callSuper = true)@EqualsAndHashCode (callSuper = false)?如果不加,是callSuper=false还是callSuper=true

【问题讨论】:

【参考方案1】:

default value 是 false。如果您不指定它并忽略警告,那将是您得到的。

是的,建议在 @Data 注释的类上添加 @EqualsAndHashCode 注释,这些类扩展了 Object 以外的其他内容。我无法告诉您是否需要 truefalse,这取决于您的类层次结构,并且需要根据具体情况进行检查。

但是,对于项目或包,如果不是 Object 的直接子类,您可以在 lombok.config 中配置调用超级方法。

lombok.equalsAndHashCode.callSuper = call

查看configuration system documentation 了解其工作原理,查看@EqualsEndHashCode documentation 了解支持的配置键。

披露:我是龙目岛开发人员。

【讨论】:

为我工作。但请记住,要让 delombok 插件选择这个配置文件,它应该放在 java 源代码根目录中,而不是在资源目录中,即在 src/main/java 中而不是在 src/main/resources 中跨度> @Roel 我想知道为什么默认值为 false。我会预料到相反的情况。另外,是否有一种等效的方法可以让 toString() 默认调用 super ?我看到我可以执行“@ToString(callSuper=true)”,但没有看到任何此类配置设置。谢谢。 在@Data 之前或之后添加@EqualsAndHashCode(callSuper=true) 是否重要? @AnnaKlein 顺序无关紧要【参考方案2】:

@EqualsAndHashCode(callSuper=true) 应该解决警告。

【讨论】:

这应该是公认的答案,因为我认为 Roel 的建议不应该做“lombok.equalsAndHashCode.callSuper = call”,而是应该为每个班级做出决定。 @AnnaKlein 我不这么认为。事实上这个答案应该是评论,这里没有新信息,你可以在我的问题中找到。我知道@EqualsAndHashCode 解决了警告。 实际上根据接受的答案(以及下面我的答案),您应该在注释中选择“callSuper=true”或“callSuper=false”。【参考方案3】:

主要的原始问题是:

加注解@EqualsAndHashCode(callSuper = true) 还是 @EqualsAndHashCode (callSuper = false)?

接受的答案基本上只是:

...这取决于...

为了对此进行扩展,@EqualsAndHashCode 上的文档提供了一些可靠的选择指导。特别是这个,恕我直言:

通过将 callSuper 设置为 true,您可以包含 equals 和 hashCode 生成方法中超类的方法。对于 hashCode, super.hashCode() 的结果包含在哈希算法中,并且 forequals,如果 super 生成的方法将返回 false 实现认为它不等于传入的对象。是 意识到并非所有的 equals 实现都能处理这种情况 适当地。但是,lombok 生成的 equals 实现确实可以处理 这种情况正确,所以你可以安全地调用你的超类等于 如果它也有一个 lombok 生成的 equals 方法。

稍微提炼一下: 如果您从一个没有状态信息的超类继承,或者它本身正在使用@Data 注释,或者具有“正确处理情况”的等值/哈希实现,则选择“callSuper=true”——我将其解释为返回状态值的适当散列。

【讨论】:

我认为这个答案很好地解释了如何在 callSuper = false 和 callSuper = true 之间进行选择。 我同意。这个解释真的很有帮助。【参考方案4】:

如果您还想比较超类的成员,请使用@EqualsAndHashCode(callSuper=true)。但是,如果您只想比较当前类中的字段,您可以使用 @EqualsAndHashCode(callSuper=false),这是 默认 选项。

如果你使用Delombok-特性,你可以看到不同之处在于,当设置为true 时,这一行被添加到生成的equals 方法if (!super.equals(o)) return false; .如果在比较两个对象时应考虑超类中的成员,则必须将其设置为 true 才能正确比较。

【讨论】:

以上是关于带有继承的@Data注释lombok上的警告等于/哈希码的主要内容,如果未能解决你的问题,请参考以下文章

带有 Jackson 的不可变 Lombok 注释类

带有 lombok 的 Bndtools“包含未知容器”

lombok在继承类上的使用

lombok的坑

java Builder 类中的附加方法(lombok 注释)

使用 `lombok` 注释和 Java JDK 8 在内存中编译 Java 类