我在第(B)行遇到编译错误“AlphaData无法通过方法调用转换转换为CAP#1”。我的解决方法是将第(A)行的indexOf()的签名更改为Object而不是T.但是,我丢失了类型检查。此外,如果“data”也被声明为BetaData类型,我希望B行能够工作。有办法做我想做的事吗?
public class Test
{
class AlphaData {} // base class for data
class BetaData extends AlphaData {} // subclass for data
abstract class BasicAdapter<T> // a generic adapter
{
abstract int indexOf (T item); //(A)
}
class BetaAdapter extends BasicAdapter<BetaData> // adapter subclass with binding
{
int indexOf (BetaData item) { return 0; }
}
BasicAdapter<? extends AlphaData> adapter = null;
Test()
{
AlphaData data = null;
int index = adapter.indexOf (data); //(B) -- compile error here
}
}
答案 0 :(得分:3)
adapter.indexOf
无法安全传递AlphaData
,因为它可能具体为BasicAdapter<BetaData>
;虽然data
具体可以是BetaData
的实例,但它可以是AlphaData
,或AlphaData
的任何其他无关子类。
要记住的首字母缩写是 PECS :
extend
super
您希望adapter
消费 AlphaData
,因此您需要BasicAdapter<? super AlphaData>
。
答案 1 :(得分:2)
这很正常。
BasicAdapter<? extends AlphaData> adapter = null
声明adapter
是某种类型的BasicAdapter
,可以扩展AlphaData
,但它可以是任何类型,因此T = any type that extends AlphaData
。因此,当你打电话
AlphaData data = null;
int index = adapter.indexOf (data); //(B) -- compile error here
您提供了AlphaData
参数,因此它不符合&#34; AlphaData
&#34;:它可能是BetaData
例如。
如果您希望它适用于任何AlphaData
,请使用:
BasicAdapter<AlphaData> adapter = null;
不使用通配符或
BasicAdapter<? super AlphaData> adapter = null;
如果data
是AlphaData
或BetaData
,则会进行编译。