Java:使用具有通配符类型参数

时间:2016-02-26 15:01:16

标签: java type-parameter

我在第(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
  }
}

2 个答案:

答案 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;

如果dataAlphaDataBetaData,则会进行编译。