Table of contents
Yes, you can, and you just need an additional line of code in the Abstract Class
. Let's take a look at how we can do so.
Context
If you have an abstract class with various subclasses, and you need to define some values through builder
method, you won't be able to do so by default because Lombok does not know if all the subclasses are annotated with toBuilder
but we can force all subclasses to implement toBuilder
method.
Setup
To make it simple, we only have an abstract class with 2 subclasses, and a couple of fields.
@SuperBuilder(toBuilder = true)
public abstract class AddressDO {
private String id;
private String street;
private String postalCode;
private String unit;
}
@SuperBuilder(toBuilder = true)
public class HomeAddressDO extends AddressDO {
private boolean isRental;
}
@SuperBuilder(toBuilder = true)
public class OfficeAddressDO extends AddressDO {
private String building;
}
Now, imagine we have a method that takes in AddressDO
as the argument
public AddressDO createAddress(AddressDO addressDO) {
// 1
return addressDO;
}
- We would like to call
toBuilder
onaddressDO
to define some fields
Problem
Take a look at the GIF below
From the GIF, we can see that even though we defined @SuperBuilder(toBuilder = true)
, we are unable to call toBuilder
method. As mentioned above, this is done on purpose by Lombok, since it cannot ensure all subclasses are annotated with toBuilder
.
Resolution
So how can we resolve this?
public abstract class AddressDO {
public abstract AddressDOBuilder<?, ?> toBuilder(); // added this
// omitted
}
We create an abstract toBuilder
method which will ensure that all subclasses also implement this method.
This is what happens if the subclass did not implement toBuilder
method
The type HomeAddressDO must implement the inherited abstract method AddressDO.toBuilder()
And now, if we try again
Limitation
The limitation is that it only allows for modification to the fields on the abstract class unless we cast it first. However, if we were to cast it, then there is no (less) need for the abstract method
in the first place.
Conclusion
We have seen how we can overcome the limitation of calling toBuilder
in an abstract class, and the limitation of doing so. I wouldn't call this a hack, but do use it only when you need it.
Source Code
As usual, the full source code is available on GitHub