[更新]实际情况比我最初提出的问题要复杂一些。我已经改变了一些代码来反映这一点。[/ UPDATE]
我对以下行为感到有点难过。给出如下代码:
interface Inter<T> {
T makeT();
void useT(T t);
}
public class Foo {
public void bar(Qux q) {
Inter<?> x = getInterForQux(q);
x.useT(x.makeT());
}
Inter<?> getInterForQux(Qux q) {
if( someTest(q) ) {
return (Inter<Integer>) mkAnInterInt();
} else {
return (Inter<Double>) mkAnInterDouble();
}
}
}
Javac给了我错误:
在&lt; capture#478 of?&gt;中使用T(捕获#478?)不能应用于(java.lang.Object)
而Eclipse给了我:
在Inter&lt; capture#1-of?&gt;类型中使用T(捕获#1-of?)的方法。是 不适用于论点 (捕获#2-of?)
显然,无论T
是什么,makeT()
的结果类型都与useT()
的参数类型相同。为什么我不能这样做?有解决方法吗?
答案 0 :(得分:4)
使用通配符时,编译器无法看到x.makeT()
的返回类型和x.useT()
的参数类型相同。为了保证它们是相同的,你应该在这里使用泛型方法:
public class Foo {
public <T> void bar(Inter<T> x) {
x.useT(x.makeT());
}
}
答案 1 :(得分:1)
这是合乎逻辑的,因为Inter<?>.makeT()
可以返回任何内容,而Inter<?>.useT(..)
会消耗任何内容,但两个 anythings 可能会有所不同。
那会解决它:
public <T> void bar(Inter<T> x) {
x.useT(x.makeT());
}
答案 2 :(得分:0)
使用捕获助手:
public void bar(Qux q) {
Inter<?> x = getInterForQux(q);
barPrivate(x);
}
private <T> void barPrivate(Inter<T> x) {
x.useT(x.makeT());
}
这为您提供了bar
的相同签名