Andrii Karaivanskyi
Andrii Karaivanskyi

Reputation: 2002

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

Please suggest how to use @Wither/@With 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:

@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

Upvotes: 8

Views: 3409

Answers (1)

Jan Rieke
Jan Rieke

Reputation: 8052

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().

Upvotes: 10

Related Questions