Lombok @builder在一个扩展另一个类的类上

zur*_*zur 28 java spring hibernate lombok

我有两个课程Child延伸Parent.我需要在类上放置@Builder注释,这样我就不需要自己创建构建器了.

package jerry;// Internal compiler error: java.lang.NullPointerException

import lombok.AllArgsConstructor;
import lombok.Builder;

@AllArgsConstructor(onConstructor=@__(@Builder))
public class Child extends Parent { 
//Multiple markers at this line
//  - Implicit super constructor Parent() is undefined. Must explicitly invoke another constructor
//  - overrides java.lang.Object.toString

   private String a;
   private int b;
   private boolean c;

}


@Builder
public class Parent {
    private double d;
    private float e;
}
Run Code Online (Sandbox Code Playgroud)

我需要能够构建这样的子实例

Child child = Child.builder().a("aVal").b(1000).c(true).d(10.1).e(20.0F).build();
Run Code Online (Sandbox Code Playgroud)

但到目前为止,我收到了代码注释中提到的错误.任何人都可以指出我正确的方向如何使用lombok或任何其他类似的库实现它?

子问题

为什么@AllArgsConstructor(onConstructor=@__(@Autowired))编译但@AllArgsConstructor(onConstructor=@__(@Builder))不是?

ham*_*est 32

https://blog.codecentric.de/en/2016/05/reducing-boilerplate-code-project-lombok/(@Builder和继承的部分)

调整到你的课程

@AllArgsConstructor
public class Parent {
  private double d;
  private float e;
}

public class Child extends Parent {
  private String a;
  private int b;
  private boolean c;

  @Builder
  public Child(String a, int b, boolean c, double d, float e) {
    super(d, e);
    this.a = a;
    this.b = b;
    this.c = c;
  }
}
Run Code Online (Sandbox Code Playgroud)

有了这个设置

Child child = Child.builder().a("aVal").b(1000).c(true).d(10.1).e(20.0F).build();
Run Code Online (Sandbox Code Playgroud)

工作正常

  • 我不知道是否可以在没有列出子构造函数/ @ Builder中的所有父+子字段的情况下完成,至少我没有找到任何这样的例子.作为一种解决方法,您可能会考虑为此特定类禁止此代码约定(至少我认为它来自某些静态代码分析工具,如PMD,Findbugs,Sonar等可以被抑制) (3认同)
  • 好点我确实尝试过......但我不能为任何函数提供超过7个参数,这是我团队中的代码约定,如果我提供超过7个参数,则构建失败.我的原始代码在超级/父类中有超过30个字段 (2认同)
  • 如果父类也具有@Builder注释,则将不起作用 (2认同)

Jan*_*eke 23

最新的lombok版本1.18.2包括新的实验@SuperBuilder.它支持超类(也是抽象类)的字段.有了它,解决方案就像这样简单:

@SuperBuilder
public class Child extends Parent {
   private String a;
   private int b;
   private boolean c;
}

@SuperBuilder
public class Parent {
    private double d;
    private float e;
}

Child instance = Child.builder().b(7).e(6.3).build();
Run Code Online (Sandbox Code Playgroud)

PS:@SuperBuilder不起作用,因为@AllArgsConstructor(onConstructor=@__(@Builder))是一个注释处理注释,lombok在编译期间转换为代码.生成,然后转换新的龙目岛标注需要注释处理的几个迭代,以及龙目不支持.@Builder相反,它是运行时可用的常规Java注释.

  • 只是提醒一句:IntelliJ Lombok插件尚不支持. (23认同)
  • IntelliJ Lombok 插件当前版本 0.27 现在支持“@SuperBuilder”。 (3认同)

小智 13

您需要@SuperBuilder(toBuilder = true)在每个对象中使用。

@Data
@SuperBuilder(toBuilder = true)
public class Parent extends Child {
}

@Data
@SuperBuilder(toBuilder = true)
public class Child {
}
Run Code Online (Sandbox Code Playgroud)