是否有可能将龙目岛的建造者公之于众?

2022-09-01 13:54:05

我在我的项目中使用龙目岛库,我无法使用在外部包中注释的类。@Builder

有没有办法让建筑商公开?

MyClass instance = new MyClass.MyClassBuilder().build();

错误是:

'MyClassBuilder()' 在 'com.foo.MyClass.MyClassBuilder' 中不是公开的。无法从外部包访问


答案 1

@Builder已经生成了公共方法,它只是构造函数的包私有。原因是他们打算让你使用静态方法,它是公共的,而不是直接使用构造函数:builder()

Foo foo = Foo.builder()
    .property("hello, world")
    .build();

如果你真的,真的,真的希望构造函数是公开的(似乎有人建议其他基于反射的库可能需要它),那么龙目岛永远不会覆盖你已经明确声明的任何东西,所以你可以用公共构造函数声明这样的骨架,龙目岛将填充其余部分,而无需将构造函数更改为包私有或任何东西。

@Builder
public class Foo
{
    private final String property;

    public static class FooBuilder
    {
        public FooBuilder() { }

        // Lombok will fill in the fields and methods
    }
}

这种允许部分实现覆盖默认行为的一般策略也适用于大多数(也许是所有)其他龙目岛注释。如果你的类是用 注释的,但你已经声明了一个方法,那么它将不用你的。@ToStringtoString

为了向您展示生成的所有内容,我编写了以下类:

@Builder
public class Foo
{
    private final String property;
}

然后,我通过delombok运行它以查看生成的所有内容。如您所见,一切都是公开的:

public class Foo
{
    private final String property;

    @java.beans.ConstructorProperties({"property"})
    Foo(final String property) {
        this.property = property;
    }

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

    public static class FooBuilder
    {
        private String property;

        FooBuilder() { }

        public FooBuilder property(final String property) {
            this.property = property;
            return this;
        }

        public Foo build() {
            return new Foo(property);
        }

        public String toString() {
            return "Foo.FooBuilder(property=" + this.property + ")";
        }
    }
}

答案 2

问题是你以错误的方式使用@Builder。

使用时,您只需要使用静态方法来调用它,然后进行构建,例如:Builder Pattern

MyClass instance = MyClass.builder().build();.

请不要再这样做了,它破坏了模式的封装,因为你直接使用内部类。此构造函数已从外部隐藏,这就是为什么您会收到不可访问的错误。相反,它为您提供了 静态方法 。newMyClassBuilderMyClassBuilderbuilder()


推荐