Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lombok @Wither Inheritance (super-/sub- classes)

Tags:

java

lombok

Please suggest how to use @Wither when inheritance applied.

I have an abstract class Parent and concrete Child. Child is supposed to be immutable. Putting @Wither on both gives me two errors:

  • The constructor Child(String) is undefined
  • The type Child must implement the inherited abstract method Parent.withA(String)
@Value
@Wither
@NonFinal
@SuperBuilder
abstract class Parent {
    String a;
}

@Value
@Wither
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
class Child extends Parent {
    String b;
}

I'd be happy to just remove @Wither and use the builder methods, but I'm refactoring a public library (trying to optimize the model classes) and I don't want compilation errors on my clients.

I also found this issue that explains the second error. But the logic of the intention is not clear https://github.com/rzwitserloot/lombok/issues/945

like image 945
Andrii Karaivanskyi Avatar asked Jun 25 '19 19:06

Andrii Karaivanskyi


People also ask

What is difference between @builder and SuperBuilder?

The @SuperBuilder annotation produces complex builder APIs for your classes. In contrast to @Builder , @SuperBuilder also works with fields from superclasses. However, it only works for types. Most importantly, it requires that all superclasses also have the @SuperBuilder annotation.

Does @builder require AllArgsConstructor?

Martin Grajcar. Your @Builder needs an @AllArgsConstructor (add it; feel free to make it private).

What is SuperBuilder Lombok?

Annotation Type SuperBuilder Lombok generates 2 inner 'builder' classes, which extend the parent class' builder class (unless your class doesn't have an extends clause). Lombok also generates a static method named builder() , and a protected constructor that takes 1 argument of the builderclass type.

How do you use super builder?

Install the Builder Theme on your Super site Click on the Theme you have selected to use. You'll see a box with the 'code' you need to copy and install on your Super site. Go to super.so and open the site where you are adding the theme. In the Builder template on your notion site, select and copy the code snippet.


Video Answer


1 Answers

Lombok is an annotation processor. Those run on each compilation unit (i.e. Java file) and do not have access to information from other compilation units. That means that Lombok cannot know anything about the contents of class Parent when processing Child.

So when generating the code for Child, Lombok does not know what wither methods are inherited from Parent. Consequently, it cannot generate an implementation for the abstract withA() from Parent.

A second problem is that the wither methods need a constructor that has all fields as parameter, including those from the superclass. That is also impossible to generate for Lombok due to the aforementioned limitation.

To make a long story short: @Wither does not work well with inheritance. I suggest putting it only on Parent and implementing it manually for Child.

Another option is to put @SuperBuilder(toBuilder=true) on both classes and then use instance.toBuilder().a("newValue").build().

like image 111
Jan Rieke Avatar answered Oct 21 '22 05:10

Jan Rieke