简体   繁体   中英

Does lombok @Builder allow extends

I have 2 classes:

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:

The return type is incompatible with A.builder().

Is this a limitation of 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 .

The latest lombok release 1.18.2 includes the new experimental @SuperBuilder . It supports inheritance and fields from superclasses (also abstract ones). The only requirement is that all superclasses must have the @SuperBuilder annotation. 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 )

From 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. In that case, Lombok will create a setter method on the builder class for every parameter of the constructor/method. 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.

Part of your question, however, was that the builder for be does not include the fields for a. That remains true, as is also for @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:

@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:

@EqualsAndHashCode(callSuper = true)

@SuperBuilder

@Data

@AllArgsConstructor

@NoArgsConstructor

Without knowing the implementation details of lombok or trying it out i'd say no because the pattern won't allow it.

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.

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. Vice versa it cannot implement the builder methods in B because those methods already exist in A. They cannot coexist by OOP design.

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.

I'd assume that instead of extending the class you'd have default values in your builder which lombok should support. Those default values then reflect what class A may support by default. In a use-case where you'd rather have B doing stuff you'd then call the builder methods and override those default values.

Edit: Oh and maybe have a look here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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