使用Lombok的@SuperBuilder注解,使用泛型最终子类无法编译通过。

4
我目前遇到了Lombok的@SuperBuilder注解和泛型的问题。我有一个抽象的父类和一个final的子类。当使用builder创建子类时,传递正确类型的值会导致编译错误。
简化后的类和接口如下:
@SuperBuilder(toBuilder = true)
public abstract class Parent<T> {

    private SomeGenericClass<?, Parent<T>> someGenericClass;
    private T value;
}

interface SomeInterface<D> {

}

class SomeGenericClass<D, S> implements SomeInterface<D> {

}

@SuperBuilder(toBuilder = true)
final class Child<T> extends Parent<T> {

}

测试代码

public class SuperBuilderTest {

    public static void main(String[] args) {
        SomeGenericClass<String, Parent<Long>> someGenericClass = new SomeGenericClass<>();

        Child<Long> child = Child.builder() 
                .someGenericClass(someGenericClass) // error: The method someGenericClass(SomeGenericClass<?,Parent<Object>>) in
                // the type Parent.ParentBuilder<Object,capture#1-of ?,capture#2-of ?> is
                // not applicable for the arguments (SomeGenericClass<String,Parent<Long>>)
                .value(10L) // error: Type mismatch: cannot convert from capture#1-of ? to Child<Long>
                .build();
    }
}

如果工作正常,那么子类本身就不再具有通用参数。所以像这样拥有子类,一切都可以编译并且完美运行。
@SuperBuilder(toBuilder = true)
final class Child extends Parent<Long> {

}

我是在做错什么还是使用 @SuperBuilder 时无法有通用的 final 类呢?


由于泛型在编译时被展开,lombok可能无法确定您希望构建器在T中接受的具体类型。如果您能避免过度使用泛型,请尽量这样做。 - 0x150
由于泛型在编译时被展开,lombok可能无法确定您希望构建器在T中接受的具体类型。如果您能避免过度使用泛型,请尽量这样做。 - 0x150
由于泛型在编译时被展开,lombok可能无法确定您希望构建器在T中接受的确切类型。如果您可以避免过度使用泛型,请尽量这样做。 - undefined
1个回答

3
builder()的类型参数(代表您正在创建的Child的类型)没有被正确推断。编译器认为它是Object。要修复此错误,只需明确指定您正在创建的Child.Builder的类型,例如。
Child.<Long>builder()
    ...

这不能被推断的原因与为什么链接thenComparing破坏了类型推断类似。
你也可以看到简单构建器发生类似的情况:
@Builder
final class Foo<T> {
    private T t;
}

// error here!
Foo<Long> f = Foo.builder().t(1L).build();

尽管在像这样的简单情况下,错误消息更清晰,说明无法将Foo<Object>转换为Foo<Long>
你的情况更复杂 - 你有一个SomeGenericClass<?, Parent<T>>字段。这意味着someGenericClass()期望的是一个SomeGenericClass<?, Parent<Object>>。而SomeGenericClass<String, Parent<Long>>肯定不能传递给它。而且你使用了SuperBuilder使事情变得更加复杂。

太棒了!非常感谢你的解释和解决方案。 - Melanie Fuchs
太棒了!非常感谢你的解释和解决方案。 - Melanie Fuchs
太棒了!非常感谢你的解释和解决方案。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接