简体   繁体   English

生成 equals/hashCode 实现但没有调用超类,即使此 class 不扩展 java.lang.Object

[英]Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object

I am getting below error while using lombok and even it doesn't allow me to set id and version while creating student instance.我在使用lombok时遇到错误,甚至它也不允许我在创建student实例时设置 id 和 version。

Multiple markers at this line
    - overrides com.example.demo.IModel.canEqual
    - Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is 
     intentional, add '@EqualsAndHashCode(callSuper=false)' to your type.
    - overrides com.example.demo.IModel.hashCode
    - overrides com.example.demo.IModel.toString
    - overrides com.example.demo.IModel.equals

IModel模型

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IModel {
    private String id;
    private String version;
}

Student学生

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Student extends IModel{
    private String firstName;
    private String lastName;
}

在此处输入图像描述

In the main method, it doesn't allow me to set the value of Id and version field在 main 方法中,它不允许我设置 Id 和版本字段的值

Student s = Student.builder().firstName("Adam").lastName("Kerr").build();

Edit-1 @sfiss - As suggested, now I changed like below, but now I am not able to set firstName and lastName, only cab set id and version Edit-1 @sfiss - 按照建议,现在我更改如下,但现在我无法设置名字和姓氏,只能设置 cab 设置 ID 和版本

Student.java学生.java

@Data
@Builder(builderMethodName = "studentBuilder")
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class Student extends IModel {
    @NotEmpty(message = "{email.notempty}")
    @Email
    private String firstName;
    private String lastName;

    public Student(final String firstName, final String lastName, final String id, final String version) {
        super(id, version);
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

IModel.java IModel.java

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class IModel {
    private String id;
    private String version;
}

There are multiple problems here, all of them relating to using lombok with inheritance:这里有多个问题,所有这些问题都与使用带有继承的 lombok 有关:

  1. Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object.生成 equals/hashCode 实现但没有调用超类,即使此类没有扩展 java.lang.Object。 If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type.如果这是故意的,请将“@EqualsAndHashCode(callSuper=false)”添加到您的类型中。

The warning is given by @Data because that usually generates equals/hashcode without the call to super.警告由@Data给出,因为这通常会在不调用 super 的情况下生成 equals/hashcode。 Fix it by adding @EqualsAndHashCode(callSuper = true) .通过添加@EqualsAndHashCode(callSuper = true)来修复它。

  1. The @Builder gives you a compile warning because it will generate two static methods with the same name in both the super- and the subclass. @Builder会给你一个编译警告,因为它会在超类和子类中生成两个同名的静态方法。 Fix it by defining @Builder(builderMethodName = "studentBuilder") on Student .通过在Student上定义@Builder(builderMethodName = "studentBuilder")来修复它。

  2. You won't be able to set superclass properties on you studentBuilder because your superclass and subclass have a default constructor.您将无法在 studentBuilder 上设置超类属性,因为您的超类和子类具有默认构造函数。 Fix it by creating a constructor and moving the @Builder annotation to it (ie annotate the constructor with @Builder , not the class ):通过创建一个构造函数并将@Builder注释移动到它来修复它(即@Builder注释构造函数,而不是 class ):

Code:代码:

@Builder(builderMethodName = "studentBuilder")
public Student(
    final String firstName,
    final String lastName,
    final String id,
    final String version) {
    super(id, version);
    this.firstName = firstName;
    this.lastName = lastName;
}

Call your builder with the correct method ( IModel.builder() vs Student.studentBuilder() ):使用正确的方法( IModel.builder()Student.studentBuilder() )调用您的构建器:

Student.studentBuilder().firstName("Name").build();

I also want to add some improvements to the above solution.我还想对上述解决方案进行一些改进。 While I like lombok as a tool (I really don't need to read that much boilerplate), the first solution to preventing boilerplate is to think whether you need all those getters and setters and ask yourself these questions:虽然我喜欢 lombok 作为一种工具(我真的不需要阅读那么多样板文件),但防止样板文件的第一个解决方案是考虑是否需要所有这些 getter 和 setter 并问自己以下问题:

  • Do you want bags of data?你想要数据包吗? It is fine for some use cases, in others you want objects more in the sense of OOP, ie don't expose your state but behavior.对于某些用例来说这很好,而在其他用例中,您更希望对象是 OOP 意义上的,即不要暴露您的状态而是行为。

  • Do you really need mutability?你真的需要可变性吗? If not, prefer @Value .如果没有,请选择@Value

  • Do you really need both constructor types (especially the no-args-constructor)?您真的需要两种构造函数类型(尤其是无参数构造函数)吗? They are part of the problem here.他们是这里问题的一部分。 Sometimes you need them for frameworks (proxies, reflection, ...) to work properly.有时您需要它们才能使框架(代理、反射等)正常工作。

  • More specific to your code: You prefixed the superclass with "I" but it is not an interface.更具体到您的代码:您在超类前面加上“I”,但它不是接口。 If it is meant as an abstract class, declare it abstract and don't give it a @Builder .如果它是一个抽象类,请将其声明为abstract类并且不要给它一个@Builder

You can use @sfiss solution您可以使用@sfiss解决方案

or或者

You can use @Getter and @Setter annotations instead of @Data annotation.您可以使用@Getter@Setter注释代替@Data注释。

I had the same problem and i resolved it in this way hope it helps you.我有同样的问题,我以这种方式解决了它希望它对你有帮助。 That help you also with abstract classes也可以帮助您使用抽象类

Student.java学生.java

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class Student extends IModel {
    @NotEmpty(message = "{email.notempty}")
    @Email
    private String firstName;
    private String lastName;

    @Builder
    public Student(final String firstName, final String lastName, final String id, final String version) {
        super(id, version);
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

IModel.java IModel.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class IModel {
    private String id;
    private String version;
}

The warning from building a Spring Boot project构建 Spring 引导项目的警告

When I built my Spring boot project, I got 20 warnings about a same thing.当我构建我的 Spring 启动项目时,我收到了 20 个关于同一件事的警告。 The warning shows: Generating equals/hashCode implementation but without a call to superclass警告显示: Generating equals/hashCode implementation but without a call to superclass

Description of the warning警告说明

This warning is from lombook, it happens when we inherit a child class from parent class by using @Data @ToString @EqualsAndHashCode, IDE will trigger the warning: Generating equals/hashCode implementation but without a call to superclass .此警告来自lombook,当我们使用@Data @ToString @EqualsAndHashCode,IDE 将触发Generating equals/hashCode implementation but without a call to superclass父类//。

Solution解决方案

There are two solutions:有两种解决方案:

  1. add annotation @EqualsAndHashCode(callSuper = true) on the class在 class 上添加注释@EqualsAndHashCode(callSuper = true)
  2. create lombook config file in the project root path: src/main/java .在项目根路径中创建 lombook 配置文件: src/main/java Note: this solution requires the version of lombook > 1.14.注意:此解决方案需要 lombook > 1.14 的版本。

I recommend the solution 2, since you will not need to add the annotation to all the required classes.我推荐解决方案 2,因为您不需要将注释添加到所有必需的类。

To impletement the solution, you need to create lombook.config in the path of src/main/java .要实现该解决方案,您需要在src/main/java的路径中创建lombook.config If you have more than one packages, you may need to create multiple config files.如果你有多个包,你可能需要创建多个配置文件。

The content of the config file includes:配置文件的内容包括:

config.stopBubbling=true
lombok.equalsAndHashCode.callSuper=call

When we rebuild our project, you will not get these warnings anymore.当我们重建我们的项目时,您将不会再收到这些警告。

Cheers!干杯!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM