仿制药通配符再次出现。

时间:2012-01-30 03:58:14

标签: java generics

我尝试在接口中引入一些泛型时遇到以下异常(实际代码简化为一般示例):

Type mismatch: cannot convert from capture#1-of ? extends Interface2<:? extends Interface1> to Interface2<:Interface1>

失败的电话是:

Interface2<Interface1> interface2Instance = interface1Instance.getInterface2ImplementorClass().newInstance();

这些是接口定义:

public interface Interface1{
  Class<? extends Interface2<? extends Interface1>> getInterface2ImplementorClass();
}

public interface Interface2<T extends Interface1> {
  public Object execute(T first, OtherClass1 second, OtherClass2 third,
        OtherClass3 baseTimeFormat) throws ChartScriptException;
}

我可以将失败的行更改为:

Interface2<**? extends** Interface1> interface2Instance = interface1Instance.getInterface2ImplementorClass().newInstance();

但是当我想打电话

时,我得到了例外
interface2Instance.execute(interface1Instance, second, third, forth);

我收到编译错误:

The method execute(capture#3-of ? extends Interface1, OtherClass1, OtherClass2, OtherClass3) in the type Interface2<:capture#3-of ? extends Interface1> is not applicable for the arguments (Interface1, OtherClass1, OtherClass2, OtherClass3)

我找不到摆脱这种混乱的方法,我有什么不对,我在哪里可以查看我正在破坏的规则?

1 个答案:

答案 0 :(得分:1)

以这种方式思考:假设Interface2ListInterface1Number。您调用代码的方式newInstance() 可以返回List<Integer>(自Integer扩展Number后),但指定List<Integer> } List<Number>无效。原因如下:

List<Integer> ints = new ArrayList<Integer>();
List<Number> nums = ints; //if this was possible
nums.add(2.0);
Integer first = ints.get(0); //then this would fail  

此技术术语是协方差,您可以在Angelika Langer's Generics FAQ上阅读更多相关信息。简而言之,泛型类型不是协变的。

鉴于您缺乏具体细节,我不确定我是否可以建议修复。您可以getInterface2ImplementorClass()返回Class<? extends Interface2<Interface1>>而不是Class<? extends Interface2<? extends Interface1>>