为什么在使用默认构造函数创建对象时,Lombok的@Builder会删除默认字段值?

基里尔

考虑以下代码:

@RunWith(JUnit4.class)
public class TestClass {

    @Test
    public void builderTest() throws Exception {
        List<Object> list = new LombokBuilderTest().list;
        assertNotNull(list);
    }
}

@NoArgsConstructor
@AllArgsConstructor
@Builder
class LombokBuilderTest {
    @Builder.Default
    List<Object> list = new ArrayList<>();
}

即使存在list属性的默认值,测试也会失败如果您注释@Builder注释,则注释将按预期工作。龙目岛为什么以这种方式工作?我希望在使用默认构造函数时将ArrayList分配给list属性。

用户名

这是一个已知的问题(12)。当使用@Builder“期望”注释类时,将使用构建器实例化该类。当您使用@NoArgsConstructor绕过构建过程的时,就会出现问题

您的示例生成的代码如下所示:

class LombokBuilderTest {

    public static class LombokBuilderTestBuilder {
        private List<Object> list;
        private boolean list$set;

        LombokBuilderTestBuilder() {}

        public LombokBuilderTestBuilder list(final List<Object> list) {
            this.list = list;
            list$set = true;
            return this;
        }

        public LombokBuilderTest build() {
            return new LombokBuilderTest((list$set ? list : LombokBuilderTest.$default$list()));
        }

        @Override
        public String toString() {
            return (("LombokBuilderTest.LombokBuilderTestBuilder(list=" + this.list) + ")");
        }
    }

    List<Object> list;

    private static List<Object> $default$list() {
        return new ArrayList<>();
    }

    public static LombokBuilderTestBuilder builder() {
        return new LombokBuilderTestBuilder();
    }

    public LombokBuilderTest() {}

    public LombokBuilderTest(final List<Object> list) {
        this.list = list;
    }

    public static void main(String[] args) {
        List<Object> list = new LombokBuilderTest().list;
        System.out.println(list);
    }
}

正如你所看到的,你的初始化值移动从外地声明的$default$list方法和使用无AGRS构造是“腐败”的实例化的唯一途径。

如第二个链接中所述,原因是,如果赋值表达式(new ArrayList<>()在您的情况下)很昂贵,那么使用构建器将使该表达式执行两次,这是性能问题。解决方法是编写您自己的无参数构造函数,并在那里进行字段初始化。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么“ A a {};” 删除默认构造函数A :: A()时进行编译?

当使用静态引用创建对象时,为什么在静态块之前执行实例块和默认构造函数?

为什么在默认构造函数中使用括号会导致变量的创建?

为什么删除副本构造函数会影响用户定义的默认构造函数?

为什么这不创建默认构造函数?

Lombok @Builder和JPA默认构造函数

为什么在使用主要构造函数进行继承时,Scala子类会创建字段的副本?

为什么你会 =delete 隐式删除默认构造函数,重点是什么?

如果琐碎的默认构造函数不执行任何操作,为什么不能使用malloc创建琐碎的可构造对象?

为什么使用默认构造函数构造std :: string对象时,其行为会有所不同?

如何使用 ForeignKey 的默认字段值?

为什么用参数创建默认的无参数构造函数会消失

自动生成默认字段构造函数的Eclipse快捷方式是什么?

在龙目岛@Builder或@Getter注释默认字段值

Javascript:默认原型字段显示未定义的对象(使用null构造函数创建的对象)

为什么将使用默认构造函数构造的对象的“ sizeof”取总为1?

删除默认构造函数。仍然可以创建对象...有时

为什么C ++ 11从std :: vector的fill构造函数原型中删除默认值?

为什么使用默认构造函数“ {}”而不是“ = default”会导致性能差异?

为什么我们应该创建默认构造函数

当对象的默认构造函数不为空时,无法创建伪造

删除副本构造函数会导致删除默认构造函数

为什么删除项目时默认属性会访问 setter

为什么clang使用libstdc ++删除包含std :: optional的类型上的显式默认构造函数?

如果工会中只有一个成员没有默认构造函数,为什么会删除它呢?

为什么更改函数的.prototype会影响已使用该构造函数创建的对象的“ instanceof”

使用带有 1 个参数的构造函数的 Dapper 时,对象返回为默认值

为什么要为联合或类联合类删除默认的默认构造函数?

PowerShell - 为什么我的脚本使用默认类字段创建对象?