如何在Lombok中调用超级构造函数

use*_*797 95 java lombok

我上课了

@Value
@NonFinal
public class A {
    int x;
    int y;
}
Run Code Online (Sandbox Code Playgroud)

我有另一个B级

@Value
public class B extends A {
    int z;
}
Run Code Online (Sandbox Code Playgroud)

lombok抛出错误,说它无法找到A()构造函数,显式调用它我想要lombok做的是给类b注释,使它生成以下代码:

public class B extends A {
    int z;
    public B( int x, int y, int z) {
        super( x , y );
        this.z = z;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们在龙目岛有注释吗?

Roe*_*ker 135

这在龙目岛是不可能的.虽然这将是一个非常好的功能,但它需要解决方案才能找到超类的构造函数.在调用Lombok的那一刻,超类只能通过名称来识别.使用import语句和类路径来查找实际的类并非易事.在编译期间,您不能仅使用反射来获取构造函数列表.

这并非完全不可能,但使用分辨率的结果val@ExtensionMethod告诉我们这很难且容易出错.

披露:我是Lombok开发人员.

  • afterConstructor 也可以很好地进行一些自动初始化 (2认同)
  • 还是不可能? (2认同)

JJ *_*kar 19

Lombok Issue#78引用了这个页面https://www.donneo.de/2015/09/16/lomboks-builder-annotation-and-inheritance/这个可爱的解释:

@AllArgsConstructor 
public class Parent {   
     private String a; 
}

public class Child extends Parent {
  private String b;

  @Builder
  public Child(String a, String b){
    super(a);
    this.b = b;   
  } 
} 
Run Code Online (Sandbox Code Playgroud)

因此,您可以使用生成的构建器,如下所示:

Child.builder().a("testA").b("testB").build(); 
Run Code Online (Sandbox Code Playgroud)

官方文件解释了这一点,但它并没有明确指出的是,你可以方便它以这种方式.

我还发现这适用于Spring Data JPA.

  • 这根本不回答这个问题.相反,它是手工完成工作,而问题是如何生成它.同时,它通过拖动@Builder使整个事情更加混乱,这与问题没有任何关系. (17认同)
  • 实际上,这对那些只想创建继承结构然后使用构建器的人非常有用.这是我使用#lombok的99%的原因.有时候我们只需要手工制作东西,让它按照我们想要的方式工作.谢谢@ jj-zabkar (5认同)

小智 15

Lombok 1.18 版引入了@SuperBuilder 注释。我们可以使用它以更简单的方式解决我们的问题。

您可以参考https://www.baeldung.com/lombok-builder-inheritance#lombok-builder-and-inheritance-3

因此,在您的子类中,您将需要这些注释:

@Data
@SuperBuilder
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
Run Code Online (Sandbox Code Playgroud)

在您的父类中:

@Data
@SuperBuilder
@NoArgsConstructor
Run Code Online (Sandbox Code Playgroud)

  • 使用 SuperBuilder,AllArgsConstructor 是否包含来自父级和子级的参数?谢谢! (7认同)

Arn*_*ter 6

Lombok不支持通过制作任何带@Value注释的类final(通过使用已知@NonFinal)来表示.

我找到的唯一解决方法是自己声明所有成员并最终使用@Data注释.这些子类需要注释@EqualsAndHashCode并需要一个显式的所有args构造函数,因为Lombok不知道如何使用all类的一个超类创建一个:

@Data
public class A {
    private final int x;
    private final int y;
}

@Data
@EqualsAndHashCode(callSuper = true)
public class B extends A {
    private final int z;

    public B(int x, int y, int z) {
        super(x, y);
        this.z = z;
    }
}
Run Code Online (Sandbox Code Playgroud)

特别是子类的构造函数使得解决方案对于具有许多成员的超类来说有点凌乱,抱歉.

  • @GerardB `@Data` 还创建 equals() 和 hashCode() 但不关心任何继承。为了确保使用超类 equals() 和 hashCode(),您需要使用 callSuper 显式生成 (3认同)
  • 你能再解释一下为什么“子类需要用`@EqualsAndHashCode`注释”吗?这个注解不是包含在`@Data`中吗?谢谢 :) (2认同)

小智 6

对于具有许多成员的超类,我建议您使用 @Delegate

@Data
public class A {
    @Delegate public class AInner{
        private final int x;
        private final int y;
    }
}

@Data
@EqualsAndHashCode(callSuper = true)
public class B extends A {
    private final int z;

    public B(A.AInner a, int z) {
        super(a);
        this.z = z;
    }
}
Run Code Online (Sandbox Code Playgroud)