我正在阅读Java教程中的以下部分:http://docs.oracle.com/javase/tutorial/java/generics/capture.html
文章一开始就指出,由于捕获类型无法转换为Object类型,所以以下代码会产生错误,因此
我有点理解这段代码为什么能够正常工作。在这段代码中,
但是我不理解的是,为什么不能直接使用这样的方法,而非使用 helper:
set
方法无法确认Object是capture#1类型。import java.util.List;
public class WildcardError {
void foo(List<?> i) {
i.set(0, i.get(0));
}
}
我在一定程度上理解这个推理。i.get返回一个Object,编译器无法确定对象是否属于capture#1类型,因此无法以类型安全的方式将其与第二个参数匹配。
然后建议使用以下代码使此方法工作:
public class WildcardFixed {
void foo(List<?> i) {
fooHelper(i);
}
// Helper method created so that the wildcard can be captured
// through type inference.
private <T> void fooHelper(List<T> l) {
l.set(0, l.get(0));
}
}
我有点理解这段代码为什么能够正常工作。在这段代码中,
l.get
被保证是类型为 T 的,所以它可以被当做 T 类型的参数来传递。但是我不理解的是,为什么不能直接使用这样的方法,而非使用 helper:
class GenericsTest {
static <K> void bar(List<K> l) {
l.set(0, l.get(l.size() - 1));
}
public static void main(String[] args) {
List<Integer> lst = Arrays.asList(1, 2, 3, 4);
bar(lst);
System.out.println(lst); // [4, 3, 2, 4]
}
}
例如,如果您要使用类型推断,为什么不直接使用显式类型泛型而不是通配符和辅助函数?在这种情况下使用通配符有什么优势?在哪些情况下您会更喜欢使用通配符而不是类型化的泛型?
static <K> void
是什么意思? - Mike 'Pomax' KamermansfooHelper
和bar
使用相同的类型。索引只是不同的(但static
与实例不同,但这也无关紧要)。 - Sotirios Delimanolis