以下应用程序在行(*)
中产生编译错误ArrayList<?> l = new ArrayList<>();
l.add(new Integer(1));
编译错误说:
error: no suitable method found for add(C<CAP#1>)
l.add(o);
为什么?我以为List应该接受任何东西
答案 0 :(得分:4)
你误解了read
的含义。
不意味着:List<?>
任何类型的对象,因此您应该能够向List
添加任何内容(它不同于原始List
或List
)。
这意味着:{{1>} 特定但未知的类型。因为类型是未知的,所以你不能在列表中添加任何内容 - 编译器不知道列表中对象的确切类型应该是什么,所以它无法检查你是否没有尝试将某些内容添加到列表中不应该被允许,因此它不允许您向列表中添加任何内容。
答案 1 :(得分:0)
我通常不喜欢使用通配符。这些是选项:
使用列表是针对具有未知类型的列表:
List<?> list = Arrays.asList(1, 2d, "3"); // can contain any Object
for (Object obj : list) { // you can retrieve them
System.out.println("--> " + obj);
}
list.add("a"); // compile error
使用<? extends Number>
可以从列表中检索数字,但仍然无法添加任何内容:
List<? extends Number> list2 = Arrays.asList(1, 2, 3); // can contain any number
for (Number n : list2) {
System.out.println("--> " + n);
}
list2.add(5); // compile error
List<? extends Number> list3 = Arrays.asList(1, 2d, 3F); // can contain any number
for (Number n : list3) {
System.out.println("--> " + n);
}
list3.add(5); // compile error
<? extends ...>
的反面是<? super ...>
。这看起来很奇怪。关键是这种List<>
的调用者可以添加适当类型的东西。检索是一个问题:
List<? super Integer> list4 = new ArrayList<>();
list4.add(1);
for (Integer num : list4) { } // compile error
for (Object num : list4) { } // this is fine, but not that useful
如果您需要灵活的数据结构,可以使用正确的超类型。比方说,List<Number>
非常灵活。如果确实需要,可以使用List<T extends Number>
等绑定类型。您可以在this answer了解更多相关信息。