简体   繁体   English

lombok @Builder 是否允许扩展

[英]Does lombok @Builder allow extends

I have 2 classes:我有2个班级:

import lombok.Builder;
@Builder
public class B extends A {
}

and

import lombok.Builder;
@Builder
public class A {
}

on the @Builder on B I get the message:B上的@Builder上,我收到消息:

The return type is incompatible with A.builder().返回类型与 A.builder() 不兼容。

Is this a limitation of lombok?这是lombok的限制吗? or something I'm doing wrong?或者我做错了什么?

If I leave the @Builder off A , then the Builder on B doesn't seem to consider the fields in A in the constructors for B .如果我将@Builder留在A ,那么B上的 Builder 似乎不会考虑B的构造函数中A中的字段。

The latest lombok release 1.18.2 includes the new experimental @SuperBuilder .最新的 lombok 版本 1.18.2 包括新的实验性@SuperBuilder It supports inheritance and fields from superclasses (also abstract ones).它支持来自超类(也是抽象类)的继承和字段。 The only requirement is that all superclasses must have the @SuperBuilder annotation.唯一的要求是所有超类都必须有@SuperBuilder注释。 With it, the solution is as simple as this:有了它,解决方案就这么简单:

@SuperBuilder
public class B extends A {
   private String b;
}

@SuperBuilder
public class A {
    private String a;
}

B instance = B.builder().b("b").a("a").build();

It is only possible with a workaround ( See #78 )只有一种解决方法才有可能(见#78

From Reinhard.codes来自Reinhard.codes

We have been using @Builder on the class itself, but you can also put it on a class's constructor or on a static method.我们一直在类本身上使用@Builder,但您也可以将它放在类的构造函数或静态方法上。 In that case, Lombok will create a setter method on the builder class for every parameter of the constructor/method.在这种情况下,Lombok 将为构造函数/方法的每个参数在构建器类上创建一个 setter 方法。 That means you can create a custom constructor with parameters for all the fields of the class including its superclass.这意味着您可以为类的所有字段(包括其超类)创建一个带有参数的自定义构造函数。

@AllArgsConstructor
public class Parent {
  private String a;
}

public class Child extends Parent {

  private String b;

  @Builder
  private Child(String a, String b){
    super(a);
    this.b = b;
  }
}

I cannot reproduce your exact problem anymore, but this may be because Lombok has evolved.我无法再重现您的确切问题,但这可能是因为 Lombok 已经进化。

Part of your question, however, was that the builder for be does not include the fields for a.但是,您的部分问题是 be 的构建器不包括 a 的字段。 That remains true, as is also for @AllArgsConstructor .这仍然是正确的, @AllArgsConstructor也是@AllArgsConstructor Inheritance is not Lombok's strong suit.继承不是龙目岛的强项。

Thad said, since you can write your constructor yourself and can put @Builder on the constructor, the following will generate a builder for B just as you wished: Thad 说,由于您可以自己编写构造函数并可以将@Builder放在构造函数上,因此以下内容将按照您的意愿为 B 生成一个构建器:

@Builder
public class A {
    String a;
}

public class B extends A {

    @Builder
    B(String a, String b) {
        super(a);
        this.b = b;
    }

    String b;
}

faced issue using lombok with java inheritance, resolved after using the below annotations on parent and child class:使用带有 java 继承的 lombok 遇到问题,在父类和子类上使用以下注释后解决:

@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)

@SuperBuilder @SuperBuilder

@Data @数据

@AllArgsConstructor @AllArgsConstructor

@NoArgsConstructor @NoArgsConstructor

Without knowing the implementation details of lombok or trying it out i'd say no because the pattern won't allow it.在不知道 lombok 的实现细节或尝试它的情况下,我会说不,因为模式不允许。

If you implement the builder pattern all of your methods (except of build() ) will always have the class which the builder exists for as return type.如果您实现构建器模式,则所有方法( build() 除外)将始终将构建器存在的类作为返回类型。

That means class A's methods will only return A. So does B always return B. If you now let B extend from A it will not override A's methods because it's return type does not match.这意味着类 A 的方法只会返回 A。B 总是返回 B。如果现在让 B 从 A 扩展,它不会覆盖 A 的方法,因为它的返回类型不匹配。 Vice versa it cannot implement the builder methods in B because those methods already exist in A. They cannot coexist by OOP design.反之亦然,它无法实现 B 中的构建器方法,因为这些方法已经存在于 A 中。它们不能通过 OOP 设计共存。

You may be able to create a generic builder but that does not solve the problem.您也许能够创建通用构建器,但这并不能解决问题。 If you really need to extend from A you're problem may come from another design decision which the builder pattern cannot solve.如果您真的需要从 A 扩展,那么您的问题可能来自另一个构建器模式无法解决的设计决策。

I'd assume that instead of extending the class you'd have default values in your builder which lombok should support.我假设不是扩展类,而是在 lombok 应该支持的构建器中使用默认值。 Those default values then reflect what class A may support by default.这些默认值然后反映了默认情况下 A 类可能支持的内容。 In a use-case where you'd rather have B doing stuff you'd then call the builder methods and override those default values.在您希望让 B 做事的用例中,您可以调用构建器方法并覆盖这些默认值。

Edit: Oh and maybe have a look here编辑:哦,也许看看这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM