当涉及到泛型和继承时,我有点纠结。总体思路是为各种组件和包含其他组件的组或容器组件提供一个构建器模式。一些组件组需要特定的组件,有些组件可以是任意组件。这就是问题所在。我认为最好用代码来解释:
public abstract class AbstractGroupComponentBuilder <T extends ComponentGroup<R>, R extends AbstractDashboardComponent> implements ComponentBuilder<ComponentGroup<R>> {
private List<ComponentBuilder<R>> children;
protected void child(ComponentBuilder<R> builder){
children.add(builder);
}
...
}
public class ComponentGroupBuilder extends AbstractGroupComponentBuilder<ComponentGroup<AbstractDashboardComponent>, AbstractDashboardComponent>{
public <T> TableBuilder<T> table(Class<T> clazz){
TableBuilder<T> builder = new TableBuilder<T>(clazz);
child(builder); // PROBLEM HERE: The method child(ComponentBuilder<AbstractDashboardComponent>) in the type AbstractGroupComponentBuilder<ComponentGroup<AbstractDashboardComponent>,AbstractDashboardComponent> is not applicable for the arguments (TableBuilder<T>)
}
...
}
public class TableBuilder<T> implements ComponentBuilder<Table> {
...
}
public class Table extends AbstractDashboardComponent{
...
}
public class ComponentGroup<T extends AbstractDashboardComponent> extends AbstractDashboardComponent {
...
}
public interface ComponentBuilder<T extends AbstractDashboardComponent> {
public T build();
}所以编译器的错误是:"The method child(ComponentBuilder<AbstractDashboardComponent>) in the type AbstractGroupComponentBuilder<ComponentGroup<AbstractDashboardComponent>,AbstractDashboardComponent> is not applicable for the arguments (TableBuilder<T>)",为什么它不兼容,因为TableBuilder<T> extends ComponentBuilder<Table>和'Table扩展了抽象AbstractDashboardComponent‘。
发布于 2019-12-05 16:58:35
在这里,您的生成器是TableBuilder<Table>类型的。这与ComponentBuilder<AbstractDashboardComponent>不兼容。程序不是ComponentBuilder,而是<>内部的东西。与普通类型不同,side <>中的内容是不变的,也就是说,这些类型必须完全匹配,不允许子类型。
原因如下:我将使用非常简单和熟悉的类型来解释它:
List<Integer> ints = new ArrayList<Integer>();
List<Number> numbers = ints; // PROBLEM LINE
numbers.add(5.0);
ints.get(0); // uhoh - that's a double and not an int!这一行标记为PROBLEM?那就不能编译了。解决办法是:
List<Integer> ints = new ArrayList<Integer>();
List<? extends Number> numbers = ints; // this is fine
numbers.add(5.0); // PROBLEM LINE
ints.get(0); // uhoh - that's a double and not an int!在本例中,错误出现在第三行:您不能向List<? extends NothingYouTypeHereCanFixThat>添加任何内容(不相关的详细信息:除了文字null)。
这就是为什么第2行现在很好。
您需要做同样的事情,并抛出一些? extends,直到它编译。
<T> =不变量;只有精确的Ts才能计算出来,但是您可以以所有想要的方式使用T。
<? extends T> =协变;T或T的任何子类型都可以,但只能调用get样式的方法。
<? super T> =对比变量;T或T的任何SUPERTYPE都可以,但只能调用add样式的方法(可以调用get,但只需获取对象)。
逆变很少出现。它让你做:
List<? super Integer> list = ...;
list.add(5); // compiles fine.
Object o = list.get(0); // all you get is `Object` here.如果您有一个List<Number>,您可以将它赋值给list变量。
https://stackoverflow.com/questions/59199777
复制相似问题