Java Generics - 无法转换<?将MyObject>扩展为<MyObject>

Use*_*345 6 java generics

为什么以下代码会出现编译错误?

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;
}
Run Code Online (Sandbox Code Playgroud)

如果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);
}
Run Code Online (Sandbox Code Playgroud)

我觉得应该允许这样做.或者我在这里遗漏了什么?有没有办法在不(Builder<MyObject>)使用构建器和必须使用@SuppressWarnings的情况下执行此操作?

还要注意我需要Builder,<? extends MyObject>因为MyObject及其Builder将被子类化(因为它是抽象的).

谢谢你的帮助!

Wil*_*sem 4

因为Foo<? extends Bar>不是一个Foo<Bar>.

Foo有一个方法:

void add (T t)
Run Code Online (Sandbox Code Playgroud)

那么根据合同,你只能添加T对象。现在,如果T被实例化为? extends Bar,我们不知道类型。接受Bar可能会导致有问题的行为:如果您有一个,则ArrayList<Foo>您希望它ArrayList仅包含Foo实例。如果您将 the 视为ArrayList<Foo>a ArrayList<SuperFoo>,则不能保证 theArrayList<Foo>只包含Foo's 。

某些语言启用协变:如果仅用作T输出,则可以说一个类Foo<T>也是相同的Foo<SuperT>(与输入相同)。但目前Java不支持这一点。然而,C# 在接口级别上做到了这一点。


归档时间:

查看次数:

3125 次

最近记录:

10 年,7 月 前