正在生成 equals/hashCode 实现但没有调用 superclass,即使此 class 没有扩展 java.lang.Object

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

我在使用 lombok 时出现以下错误,甚至它不允许我在创建 student 实例时设置 ID 和版本。

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

模型

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

学生

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

在main方法中,不允许我设置Id和version字段的值

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

编辑-1 @sfiss - 按照建议,现在我像下面这样改变了,但现在我无法设置 firstName 和 lastName,只能设置 cab id 和 version

Student.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

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

这里有多个问题,所有问题都与使用带继承的 lombok 有关:

  1. 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.

警告由 @Data 发出,因为它通常会在不调用 super 的情况下生成 equals/hashcode。通过添加 @EqualsAndHashCode(callSuper = true).

来修复它
  1. @Builder 给你一个编译警告,因为它会在 super- 和 subclass 中生成两个同名的静态方法。通过在 Student 上定义 @Builder(builderMethodName = "studentBuilder") 来修复它。

  2. 您将无法在 studentBuilder 上设置 superclass 属性,因为您的 superclass 和 subclass 具有默认构造函数。通过创建构造函数并将 @Builder 注释移动到它来修复它(即 @Builder 注释构造函数,而不是 class):

代码:

@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;
}

使用正确的方法调用构建器(IModel.builder() vs Student.studentBuilder()):

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

我还想对上述解决方案进行一些改进。虽然我喜欢将 lombok 作为一种工具(我真的不需要阅读那么多样板文件),但防止样板文件的第一个解决方案是考虑是否需要所有这些 getter 和 setter 并询问你自己这些问题:

  • 你想要一袋数据吗?这对于某些用例来说很好,在其他用例中,您希望对象在 OOP 的意义上更多,即不要公开您的状态,而是公开行为。

  • 你真的需要可变性吗?如果没有,更喜欢 @Value.

  • 您真的需要两种构造函数类型(尤其是 no-args-constructor)吗?他们是这里问题的一部分。有时您需要它们让框架(代理、反射等)正常工作。

  • 更具体到您的代码:您在 superclass 前加上 "I" 前缀,但它不是接口。如果它意味着抽象 class,请声明它 abstract 并且不要给它一个 @Builder.

您可以使用解决方案

您可以使用 @Getter@Setter 注释代替 @Data 注释。

我遇到了同样的问题,我用这种方法解决了希望对你有帮助。 那帮助摘要类

Student.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

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