java - 覆盖 lombok 构建器并更改值类型

标签 java java-8 lombok builder

我有以下带有 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/

相关文章:

java - Java 8 中的异步方法后跟并行执行的方法

java - (List<?>) 从接口(interface)表示的 "generics"对象列表到实现它的具体类型意味着什么?

gradle - 重复生成的类 gradle 输出 (build/...) 与 intellij 输出 (out/...)

java - Lombok @Getter 和 @Setter 无法获取或设置对象的值

java - 使用 JNA 将 VB 代码转换为 Java,越来越接近

java - 终止或中断 java 8 流循环

java - JXCollapsiblePane 与 JXMultiSplitPane

java - Gradle Swagger CodeGen DefaultGenerator CodegenConfigurator 添加 Lombok

java - 将模拟bean注入(inject)到测试对象中

java - Liquibase 日志级别更改