为什么以下代码会出现编译错误?
public MyObject(Builder<? extends MyObject> builder) {
// Type mismatch: cannot convert from MyObject.Builder<capture#5-of ? extends MyObject> to MyObject.Builder<MyObject>
Builder<MyObject> myObjBuilder = builder;
}
如果Builder类型是MyObject的子类,那么为什么不能将构建器分配给MyObject?我需要这样做,因为我无法使用构建器的MyObject类型的对象。看一下这段代码,例如:
public MyObject(Builder<? extends MyObject> builder) {
// The method getData(capture#8-of ? extends MyObject) in the type Builder<capture#8-of ? extends MyObject> is not applicable for the arguments (MyObject)
this.data = builder.getData(this);
}
我觉得应该允许这样做。或者我在这里遗漏了什么?有没有办法在不将构建器强制转换为(Builder<MyObject>)
并且必须使用@SuppressWarnings的情况下执行此操作?
另请注意,我需要构建器<? extends MyObject>
,因为MyObject及其构建器将被子类化(因为它是抽象的)。
感谢您的帮助!
答案 0 :(得分:4)
因为Foo<? extends Bar>
不是Foo<Bar>
。
说Foo
有一个方法:
void add (T t)
然后按合同,您只能添加T
个对象。现在,如果将T
实例化为? extends Bar
,我们就不知道该类型。接受Bar
可能会导致有问题的行为:如果您有ArrayList<Foo>
,则期望ArrayList
仅包含Foo
个实例。如果您将ArrayList<Foo>
视为ArrayList<SuperFoo>
,则无法保证ArrayList<Foo>
仅包含Foo
。
某些语言启用covariance:如果您只使用T
作为输出,则可以说类Foo<T>
也与Foo<SuperT>
相同(相同)输入)。但目前Java并不支持这一点。然而,C#在接口级别上。