Mel*_*chs 5 java generics builder lombok
我目前面临 Lombok 注释和泛型的问题@SuperBuilder。我有一个abstract家长班和一个final孩子班。使用构建器创建子级时,传递正确类型的值会导致编译错误。
简化的类和接口
@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> {
}
Run Code Online (Sandbox Code Playgroud)
测试代码
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();
}
}
Run Code Online (Sandbox Code Playgroud)
如果可行,只要子级本身不再具有通用参数。因此,有了这样的孩子,一切都会编译并运行得很好:
@SuperBuilder(toBuilder = true)
final class Child extends Parent<Long> {
}
Run Code Online (Sandbox Code Playgroud)
final我做错了什么或者在使用时不可能有通用类吗@SuperBuilder?
类型参数builder()(代表您正在创建的类型Child)未正确推断。编译器认为它是Object. 要修复错误,只需明确Child.Builder您正在创建的类型,例如
Child.<Long>builder()
...
Run Code Online (Sandbox Code Playgroud)
无法推断的原因与链接thenComparings 破坏类型推断的原因类似。
您也可以在简单的构建器中看到类似的情况发生:
@Builder
final class Foo<T> {
private T t;
}
// error here!
Foo<Long> f = Foo.builder().t(1L).build();
Run Code Online (Sandbox Code Playgroud)
尽管在这样的简单情况下,错误消息更加清晰,指出您无法将 a 转换Foo<Object>为Foo<Long>。
你的情况更复杂——你有一个SomeGenericClass<?, Parent<T>>领域。这意味着someGenericClass()正在期待一个SomeGenericClass<?, Parent<Object>>. ASomeGenericClass<String, Parent<Long>>当然不能传递给它。您正在使用的事实SuperBuilder使事情变得更加复杂。