Java Generics:通配符(?)作为参数和返回类型

时间:2012-05-11 08:57:48

标签: java generics

我有以下代码段:

public void reorder(int fromIndex, int toIndex) {
    getElements().add(toIndex, getElements().remove(fromIndex));
}

此处,方法getElements的返回类型为List<?>remove方法的返回类型为?add方法的参数显示为int index, ? element。所以我的假设是,因为remove方法的返回类型和add方法的第二个参数是相同的 - ? - 方法调用必须成功。但是,我错了,上面的代码段会导致错误:

The method add(int, capture#17-of ?) 
in the type List<capture#17-of ?> 
is not applicable for the arguments (int, capture#18-of ?)

在这里,我没有对列表的任何直接访问,我不知道它是getElements方法返回的原始类型。我想要的是删除fromIndex上的项目并将其放在toIndex。那么,我该如何实现呢?我对仿制药的理解是否有任何问题?

3 个答案:

答案 0 :(得分:4)

不不不!使用捕获:

public void reorder(int fromIndex, int toIndex) {
    reorderWithCapture(getElements());
}

private <E> void reorderWithCapture(List<E> elements) {
    elements.add(toIndex, elements.remove(fromIndex));
}

答案 1 :(得分:2)

只需添加一个使?具体的强制转换:

public void reorder(int fromIndex, int toIndex) {
  final List<Object> els = (List<Object>)getElements();
  els.add(toIndex, els.remove(fromIndex));
}

由于您只是重新排列列表中的元素,因此不会造成任何麻烦。但是如果你看到那种回归价值,我必须说设计有问题。

答案 2 :(得分:1)

通配符?表示任何(未知)类型,而不是一种特定类型。因此编译器无法验证remove调用中使用的任何类型是否与getElements中使用的任何类型相同add来电。这可以从错误消息中看出,其中前者被描述为capture#18-of ?而后者被描述为capture#17-of ?。这些被编译器视为两种不同的,不相关的类型。

由于你显然无法修改这些方法的定义(尽管根据你的描述肯定看起来很腥),这里最不好的选择可能是@Marko建议的:分离过程的两个步骤并使用temp具有具体类型参数(Object)的变量,以使编译器满意。