Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheritance with lombok annotation get errors

In my project, lombok is used to avoid writing getters and setters for a class. I have two classes Child extends Parent:

@Value
@Builder
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Parent {
    @Nonnull
    @JsonProperty("personId")
    private final String personId;

    @JsonProperty("personTag")
    private final String personTag;
    ...
}

And

@Value
@Builder
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Child extends Parent {
    @Nonnull
    @JsonProperty("childId")
    private final String childId;
    ...
}

But this doesn't seems work as no default constructor available in Parent. I'm not familiar with the lombok annotation. Is there any good way to extend the Base class and use the lombok annotation at the same time?

like image 480
Kevin Avatar asked Sep 15 '18 02:09

Kevin


2 Answers

Class hierarchies + lombok doesn't work particularly well, in the sense that the lombok operations done on your Child class don't know anything about parent.

However, your specific question seems answerable:

The Parent class has a constructor that takes all fields, because you asked lombok to make this constructor via @AllArgsConstructor. Therefore, it does not have a no-args constructor. If you want both constructors (the one that takes all fields + a second one that takes no arguments, a.k.a. the default constructor), also add a @NoArgsConstructor annotation to tell lombok that you want that.

NB: @Builder does not work with hierarchy either, but the fresh new @SuperBuilder feature does. I'm pretty sure you want to replace @Builder with @SuperBuilder here. SuperBuilder requires that ALL classes in the hierarchy are annotated with @SuperBuilder and not @Builder.

like image 70
rzwitserloot Avatar answered Nov 05 '22 17:11

rzwitserloot


TL;DR: add @NonFinal annotation to your superclass

Details: @Value annotation makes the class final, so you cannot inherit from it. Experimental @NonFinal annotation should prevent this.

import lombok.Value;
import lombok.experimental.NonFinal;

@Value
@NonFinal
public class Parent {

REF: https://projectlombok.org/features/Value


NOTE: For performance reasons (if it matters) final (value) objects can be (theoretically) super fast. The optimizer can allocate them in the stack memory, or reuse the same stack block in cycles, so no GC overheads.

(This is similar to how .NET structure value objects are usually allocated by .NET framework)

By adding @NonFinal such an optimization opportunity disappears.

like image 39
epox Avatar answered Nov 05 '22 16:11

epox