Java 泛型 - 无法从 <?将 MyObject> 扩展到 <MyObject>
Java Generics - Cannot convert from <? extends MyObject> to <MyObject>
为什么下面的代码会报编译错误?
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 的情况下执行此操作?
另请注意,我需要 Builder 为 <? extends MyObject>
,因为 MyObject 及其 Builder 将被子类化(因为它是抽象的)。
感谢您的帮助!
因为 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
作为输出,你可以说class Foo<T>
与[=27=相同] 以及(与输入相同)。但目前 Java 不支持。然而,C# 在接口级别执行。
为什么下面的代码会报编译错误?
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 的情况下执行此操作?
另请注意,我需要 Builder 为 <? extends MyObject>
,因为 MyObject 及其 Builder 将被子类化(因为它是抽象的)。
感谢您的帮助!
因为 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
作为输出,你可以说class Foo<T>
与[=27=相同] 以及(与输入相同)。但目前 Java 不支持。然而,C# 在接口级别执行。