Lombok @Builder 用于具有强制字段的多级继承中的类
Posted
技术标签:
【中文标题】Lombok @Builder 用于具有强制字段的多级继承中的类【英文标题】:Lombok @Builder for a class in multiple level of inheritance with mandatory fields 【发布时间】:2021-11-21 17:40:38 【问题描述】:我想在更深层次的继承中为类实现 Builder 模式,其中一些字段是必需的(消息、原因)和一些可选的(myOptField1、myOptField2...),使用 Lombok @Builder 并假设父类不能更改。所以我已经像这样实现了我自己的 builder():
@Builder(toBuilder = true)
@Getter
public class MyException extends Exception
private int myOptField1;
private String myOptField2;
public static MyExceptionBuilder builder(String message, Throwable cause)
return new MyException(message, cause).toBuilder();
public MyException(String message, Throwable cause)
super(message, cause);
那么这个类的使用可以是这样的:
MyException
.builder("Mandatory message", new SpecificException("specificCause"))
.myOptField2("value")
.build();
在 IntelliJ Idea 中,一切似乎都很好,但出现编译错误:
java: constructor MyException in class com.myproject.MyException cannot be applied to given types;
required: java.lang.String,java.lang.Throwable
found: int,java.lang.String
reason: actual and formal argument lists differ in length
所以编译器只能看到 Lombok @Builder (=@AllArgsConstructor) 生成的构造函数,而看不到我的带有参数 java.lang.String,java.lang.Throwable 的构造函数。有没有更好的方法来解决这个问题?
【问题讨论】:
您可以尝试将@Builder 注释添加到您的构建器方法而不是类本身吗? 【参考方案1】:我唯一想到的就是覆盖build()
&toBuilder()
方法。 Lombok 根据不适合您的情况的字段生成自己的构造函数,而且 Lombok 对继承类中的字段一无所知。
在我看来,实现自己的 Builder 而不是破解 Lombok 解决方案更容易。
@Builder(toBuilder = true)
@Getter
public class MyException extends Exception
private int myOptField1;
private String myOptField2;
public static MyExceptionBuilder builder(String message, Throwable cause)
return new MyException(message, cause).toBuilder();
public MyException(String message, Throwable cause)
super(message, cause);
MyExceptionBuilder toBuilder()
....
public static class MyExceptionBuilder
public MyException build()
....
【讨论】:
【参考方案2】:构建器模式的要点是不变性,因此您的可选值应该是最终的。您可以像这样将@Builder 放入构造函数中:
@Getter
static class MyException extends Exception
private final int myOptField1;
private final String myOptField2;
@Builder
public MyException(String message, Throwable cause, int myOptField1, String myOptField2)
super(message, cause);
this.myOptField1 = myOptField1;
this.myOptField2 = myOptField2;
MyException.builder().cause(new Exception()).message("").myOptField1(1).myOptField2("").build();
但不能保证强制值。如果它对您很重要,您可以制作自己的构建器。在 IntelliJ 中,转到 Refactor -> Delombok -> 选择 @Builder。您可以从@Builder 中看到生成的代码并自行修改。
【讨论】:
以上是关于Lombok @Builder 用于具有强制字段的多级继承中的类的主要内容,如果未能解决你的问题,请参考以下文章