【问题标题】:Inheritance with lombok annotation get errors带有 lombok 注释的继承得到错误
【发布时间】:2018-09-15 02:16:16
【问题描述】:

在我的项目中,lombok 用于避免为类编写 getter 和 setter。 我有两个类Child 扩展Parent

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

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

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

但这似乎不起作用,因为Parent 中没有可用的默认构造函数。我不熟悉 lombok 注释。有什么好的方法可以扩展Base类,同时使用lombok注解吗?

【问题讨论】:

  • 使用@NoArgsConstructor作为默认构造函数
  • 也许您将遇到的错误添加到您的问题中?你是不是故意让类不可变?
  • 嗨@pirho 抛出两个错误:“Parent 中没有可用的默认构造函数”和“无法从最终 Parent 继承”。我认为 rzwitserloot 在下面的评论回答了我的部分问题。我也不确定处理我的用例的正确方法 - 扩展父模型或创建新模型。
  • 嘿@MaruthiAdithya 你是对的,这似乎是“无默认构造函数”错误的可行解决方案。
  • 在 Java 中,您不能对子类强制执行不变性。因此,lombok 在使用@Value 时创建了final 类,以确保没有人创建(可能是可变的)子类。如果您确定没有人会在您的情况下这样做,您仍然可以在没有@Value 的情况下使超类不可变:省略设置器,并设置字段final。如果使用@SuperBuilder 创建实例还不够(请参阅@rzwitserloot 的答案),则必须创建一个手动构造函数,其中所有字段都作为Child 中的参数调用@AllArgsConstructorParent

标签: java inheritance constructor builder lombok


【解决方案1】:

类层次结构 + lombok 效果不是特别好,因为在您的 Child 类上完成的 lombok 操作对父类一无所知。

但是,您的具体问题似乎可以回答:

Parent 类有一个构造函数,它接受所有字段,因为您要求 lombok 通过 @AllArgsConstructor 创建这个构造函数。因此,它没有无参数构造函数。如果你想要两个构造函数(一个接受所有字段 + 第二个不接受参数,也就是默认构造函数),还添加一个 @NoArgsConstructor 注释告诉 lombok 你想要那个。

注意:@Builder 也不适用于层次结构,但全新的 @SuperBuilder 功能可以。我很确定你想在这里用@SuperBuilder 替换@Builder。 SuperBuilder 要求层次结构中的所有类都使用@SuperBuilder 而非@Builder 进行注释。

【讨论】:

  • 是的,添加另一个“@NoArgsConstructor”注释修复了“无默认构造函数”问题。一个可能的解决方法似乎是:用“@Data”替换“@Value”并删除父模型中字段的“final”。但这会使 Parent 可变。基本模型(父模型)已在使用中。我不确定扩展它是否好。或者,也许创建一个涵盖 Child 用例的新模型版本是更好的解决方案?
【解决方案2】:

TL;DR:将 @NonFinal 注释添加到您的超类

详细信息:@Value 注释使类 final,因此您不能从它继承。实验性的@NonFinal 注释应该可以防止这种情况发生。

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

@Value
@NonFinal
public class Parent {

参考号:https://projectlombok.org/features/Value


注意:出于性能原因(如果重要的话)最终(价值)对象可以(理论上)超级快。优化器可以将它们分配到栈内存中,也可以循环重用同一个栈块,因此没有 GC 开销。

(这类似于 .NET 框架通常分配的 .NET structure 值对象)

通过添加@NonFinal,这样的优化机会就消失了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 2016-11-29
    • 2023-03-10
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多