Lombok @SuperBuilder 继承与泛型总是显示“捕获?”

问题描述 投票:0回答:1

我正在尝试创建许多具有继承层次结构的类。为了实例化这些类,我想使用构建器,但我也想重写这些构建器中的一些方法。既然有继承,我就用@SuperBuilder来实现。但是加入泛型,一切都变得有点混乱,我不确定如何正确修复它。

我有一个基类定义为:

@SuperBuilder
public class Base<T> {
    protected T payload;
    protected String name;
    protected String attribute;
}

现在我想创建一个新类来扩展这个类,但会绑定有效负载属性的类型,并设置一些默认值,所以我将其定义为:

@SuperBuilder
public class ChildA<T extends Payload> extends Base<T> {


    public abstract static class ChildABuilder
            <T extends Payload, C extends ChildA<T>, B extends ChildA.ChildABuilder<T, C, B>>
            extends Base.BaseBuilder<T, C, B> {

        ChildABuilder() {
            super.name("CHILD A");
        }

        @Override
        public B payload(T payload) {
            return super.payload(payload).attribute(payload.attribute());
        }
    }
}

但这会抛出一个错误,说“两种方法都有相同的擦除,但都不隐藏对方”。所以我将父级

@SuperBuilder
更改为
@SuperBuilder(builderMethodName = "baseBuilder")
,解决了这个问题。 (我们假设 Payload 也有一个“attribute”属性,只是为了说明我的问题)。

但是,我无法实际构建一个实例。尝试做以下事情:

ChildA<PayloadChild> childA = ChildA.<PayloadChild>builder()
                .payload(new PayloadChild())
                .build();

导致

.payload(new PayloadChild())
出现问题,指出需要 T,但提供了 PayloadChild。 (假设 PayloadChild 扩展了 Payload)。

我尝试过“delomboking”代码,并制作了一个有点功能的类。但我在构建基类实例时仍然遇到问题,例如用于测试,并且我不认为 delomboking 应该是解决方案。

我做错了什么?需要进行哪些更改才能发挥作用?

编辑1: 在 @Sweeper 的评论之后,我意识到我的代码确实有效。引发错误的是 IntelIJ IDE(或 Lombok 插件),但它实际上可以编译并运行。 我暂时保留这个问题,以防有人有一些解决方法或让 IDE 不抱怨的东西。

java lombok
1个回答
0
投票

您遇到的第一个问题(“...具有相同的擦除,但两者都没有隐藏另一个”)是由于Java语言的限制。静态方法不能被重写,只能互相隐藏。在这种情况下,

builder()
子类中的
ChildA
方法不会隐藏
Base
超类中的方法,因为它们具有不同的签名。但是,编译器无法静态地确定您要调用哪个方法(因为“它们具有相同的擦除”,即删除类型参数后它们看起来完全相同)。

您已经找到了解决方案:重命名其中一个

builder()
方法。这是一个有效的解决方案。但是,从您的代码来看,它似乎并不打算直接使用
Base
类。如果是这样的话,可能会更好

  • 使用
    builder()
     删除 
    Base
     类中的 
    @SuperBuilder(builderMethodName = "")
  • 方法
  • 使
    Base
    类抽象。

通过这种方式,您将不会有额外的静态

builder()
方法,如果开发人员在自动完成中看到它,可能会感到困惑。

您描述的第二个问题实际上只出现在IntelliJ中,但在Eclipse中或使用

javac
编译时不会出现。考虑提交错误

© www.soinside.com 2019 - 2024. All rights reserved.