31

I have classes that extend an abstract class and I don't want to put @Builder on top of the all child classes.

Is there any way to implement Lombok @Builder for an abstract class?

Jan Rieke
  • 7,027
  • 2
  • 20
  • 30
sam
  • 1,073
  • 4
  • 13
  • 27
  • How is that supposed to work? Can you show how you would want to invoke the Builder afterwards? Especially if the child class adds new members. – luk2302 Jul 06 '18 at 10:58
  • @luk2302 I don't want to add new fields from child – sam Jul 06 '18 at 11:01

2 Answers2

54

This is possible with lombok 1.18.2 (and above) using the new (experimental) annotation @SuperBuilder. The only restriction is that every class in the hierarchy must have the @SuperBuilder annotation. There is no way around putting @SuperBuilder on all subclasses, because Lombok cannot know all subclasses at compile time. See the lombok documentation for details.

Example:

@SuperBuilder
public abstract class Superclass {
    private int field1;
}

@SuperBuilder
public class Subclass extends Superclass {
    private int field2;
}

Subclass instance = Subclass.builder().field1(1).field2(2).build();
Jan Rieke
  • 7,027
  • 2
  • 20
  • 30
  • Is there a way to make @SuperBuilder work with final fields on the abstract class? – burtmacklin16 Feb 20 '20 at 02:58
  • 1
    It should work just without anything special. Either you found a bug or there is something else wrong. Could you open a new question with some example code to reproduce your problem? I'll look into it. – Jan Rieke Feb 20 '20 at 10:19
  • I've opened https://stackoverflow.com/questions/60322188/how-to-use-lombok-superbuilder-on-abstract-classes-with-final-fields to track my question. – burtmacklin16 Feb 20 '20 at 14:27
13

Not possible at all. The builder is generated into the super class during compiling and it can not have any knowledge of the possible sub classes that will eventually implement it.

For example, the sub class could have constructors that have to be used for the instance to have a valid state and Lombok can not have any knowledge about it when the builder is generated.

Take a look at the example code in @Builder documentation. You'll quickly see that it is just impossible to adapt it into instantiating an unknown sub class.

Torben
  • 3,805
  • 26
  • 31
  • So can I pass variable to base class by adding @Builder into sub class? – sam Jul 06 '18 at 11:24
  • 1
    @Builder doesn't really work too well with inheritance. It's intention is to provide a builder for instantiating an object and nothing further. So whatever you need for constructing your instance has to be defined in that class. Just like what you would do when working without a builder. I don't know if it is of any use to you, but fluent accessors in the abstract super class might be useful. Then you could write "Child.build().setSuperFieldA(...).setSuperFieldB(...)". – Torben Jul 06 '18 at 11:56