我有以下带有 Lombok @Builder
的类,其中我重写一个构建器方法以将输入字符串列表转换为枚举列表(字段 barList
):
(其他字段number
我仍然使用默认方法)
import java.util.List;
import java.util.stream.Collectors;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder(toBuilder = true)
public class Foo {
private List<BarEnum> barList;
private int number;
public static class FooBuilder {
private List<BarEnum> barList;
public FooBuilder barList(List<String> barStringList) {
this.barList = barStringList.stream()
.map(barString -> BarEnum.valueOf(barString))
.collect(Collectors.toList());
return this;
}
}
}
编译时,我在上面的 @Builder(toBuilder = true)
行上收到此错误:
incompatible types: java.util.List<com.mypackage.BarEnum> cannot be converted to java.util.List<java.lang.String>
我找不到任何可以覆盖默认构建器方法并更改值类型的答案。可以这样做吗?
最佳答案
首先我们运行 delombok 以更好地了解正在发生的情况,然后编译输出。
java -jar lombok.jar delombok -p Foo.java >Foo2.java
# Rename Foo2.java or make the `class Foo` declaration non-public
javac Foo2.java
让我们:
Foo2.java:63: error: incompatible types: List<BarEnum> cannot be converted to List<String>
return new Foo.FooBuilder().barList(this.barList).number(this.number);
^
然后答案就很明确了:Lombok 需要 barList(List<BarEnum>)
构建器 barList 方法的变体存在。通过自己编写,lombok 不会生成自己的版本。
Lombok 核心开发人员在此发言:我们不这样做,因为很难确定是否存在签名冲突。因此,我们注意到一个方法与我们想要生成的方法同名,并且具有相同的参数计数,我们不做任何进一步的分析:这是一个“匹配”,意味着 lombok 不再生成这个方法,假设你已经承担了这件事的责任。这是一个很好很好的例子:不可能有 barList(List<BarEnum>)
除了您的显式 barList(List<String>)
之外的方法方法,因为你不能有两种仅在参数的泛型部分不同的方法! (尝试一下 - 不会编译)。
因此,你在这里的做法根本站不住脚。修复相当简单 - 使自定义方法类似于:
public FooBuilder barStringList(List<String> barStringList) { .. }
即给它另一个名字。现在lombok也会生成barList(List<BarEnum>)
一切都会好起来的。
如果你想要barlist(List<BarEnum>)
变体不存在,则不存在,但您必须手写 toBuilder()
部分内容:到那时,如果您开始有效地删除作为“setter”所需的方法来使其工作,那么 lombok 不再可能自动知道如何将实例转换为预填充的构建器.
免责声明:我是一名核心 lombok 开发人员。
关于java - 覆盖 lombok 构建器并更改值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70443229/