我想在这里获取G.myUglyList列表的内容并将其传递给Outer.send()方法。我不明白为什么这会给编译错误。 ? extends Inner是I类参数化Outer的类型。那么为什么拒绝一个内心传递给它呢?它想要一个“?extends Inner”,这不是一种类型。
我希望列表声明为List<Outer<? extends Inner>>
,因此它可以采用Inner的子类型。 (请参阅下面的编辑了解原因)
interface Outer<T> {
void send(T message);
}
interface Inner {}
interface Inner2 extends Inner {}
public class G {
List<Outer<? extends Inner>> myUglyList;
void foo() {
Inner xxx = null;
for (Outer<? extends Inner> outer : myUglyList) {
outer.send(xxx); //error
}
}
}
我收到此错误:
error: method send in interface Outer<T#2> cannot be applied to given types;
required: CAP#1
found: Inner<T#1>
reason: actual argument Inner<T#1> cannot be converted to CAP#1 by method invocation conversion
where T#1,T#2 are type-variables:
T#1 extends Object declared in class G
T#2 extends Object declared in interface Outer
where CAP#1 is a fresh type-variable:
CAP#1 extends Inner<T#1> from capture of ? extends Inner<T#1>
编辑:我得到了很多答案,只要列出List<Outer<Inner>>
类型的列表,但这是不正确的。如果我这样做,我将不能够添加Inner的子类型。如果我尝试添加Outer<Inner2>
,则会失败。因此列表必须是List<Outer<? extends Inner>>
类型。
interface Inner2 extends Inner {}
class G {
void foo() {
Outer<Inner2> foiled = null;
myUglyList.add(foiled); //this will fail if list is of type List<Outer<Inner>>
Inner xxx = null;
for (Outer<? extends Inner> outer : myUglyList) {
outer.send(xxx); //error
}
答案 0 :(得分:3)
更改您的代码:
interface Outer<T> {
void send(T message);
}
interface Inner {}
interface Inner2 extends Inner {}
public class G {
List<Outer<Inner>> myUglyList;
void foo() {
Inner2 xxx = null;
for (Outer<Inner> outer : myUglyList) {
outer.send(xxx); //error
}
}
}
它将编译
<强>更新强>
// No matter if you put 'T extends Inner' here, the 'add' won't compile
interface Outer<T extends Inner> {
void send(T message);
}
interface Inner {}
interface Inner2 extends Inner {}
public class G {
List<Outer<Inner>> myUglyList;
void foo() {
Outer<Inner2> foiled = null;
// This way, the 'add' invocation will compile, but it
// breaks the generic and generates a warning.
//
// Casting 'foiled' to (Outer<Inner>) will also fail
// because the compiler sees Outer<Inner2> as complete different type
// from Outer<Inner>
myUglyList.add((Outer) foiled);
Inner xxx = null;
for (Outer<Inner> outer : myUglyList) {
outer.send(xxx); //error
}
}
}
答案 1 :(得分:2)
只需声明
List<Outer<Inner>> myUglyList;
然后,您可以无限制地添加Inner
的子类型。通过声明
List<Outer<? extends Inner>> myUglyList;
您说myUglyList
是“Outer<some specific (but unknown) subtype of Inner>
的列表”。那不是你想要的。
答案 2 :(得分:2)
outer
属于Outer<? extends Inner>
类型,即某个未知的Inner
子类型,其send
方法采用同一子类型的对象。
例如,outer
可能属于Outer<OtherInner>
类型,然后outer.send
需要OtherInner
,因此outer.send(xxx)
会出错。
答案 3 :(得分:1)
for (Outer<? extends Inner> outer : myUglyList) {
outer.send(xxx); //error
}
其中,Outer<? extends Inner> outer
,因此实际类型未知(?
)。 send
采取了一些未知的扩展Inner
的内容,outer
还有一些扩展Inner
但仍未知的内容。
<强>更新强>
interface Outer<T extends Inner> {
void send(T message); //this can take instance of subtype of Inner
}
interface Inner {}
interface Inner2 extends Inner {}
class G {
List<Outer<Inner>> myUglyList; //you can add instances of subtypes of Inner
void foo() {
Inner xxx = null;
for (Outer<Inner> outer : myUglyList) {
outer.send(xxx); //error
}
}
}
答案 4 :(得分:1)
PECS - 制作人extends
消费者super
由于outer
是使用extends
参数化的,因此您无法将任何(null
除外)传递到其send
方法中。