我已经阅读了有关通配符捕获如何在Java中工作的文章。 In this section,作者演示了编译器如何捕获通配符类型并进行一些转换。
但是我在编译以下代码后感到困惑(代码本身没有任何意义,我只想测试Java中捕获的通配符)
public class Test {
public static void main(String[] args) {
}
public static void copy(List<?> src, List<?> dest) {
for (int i = 0; i < dest.size(); i++) {
dest.set(i, src.get(i));
}
}
}
我遇到了编译时错误:
Error:(9, 32) java: incompatible types: java.lang.Object cannot be converted to capture#1 of ?
根据该帖子,编译器应该能够捕获通配符类型src
并将其转换为类似List<capture#2>
但是为什么错误提示src.get(i)
的类型是Object
,而不是capture#2
这样的东西?
如果该帖子有误,通配符捕获实际上如何工作?
答案 0 :(得分:1)
我没有看过链接,但我真的怀疑这与您在此处发布的内容相同...
有效地List<?> src
意味着您可以从List
检索的唯一内容是Object
(除非您知道并可以对其进行强制转换,可能会失败,当然:String s = (String) src.get(0);
)。
List<?> dest
意味着此目的地实际上是只读,因为?
意味着您可以添加任何内容,String
,Integer
,等等-添加不同类型时会破坏其完整性,因此这是禁止的。
答案 1 :(得分:0)
类型List<?>
的参数可以接收任何内容的列表。因此,您可以为List<Integer>
输入一个src
,为List<String>
输入一个dest
。然后,您将在出错的行中将Integer
添加到String
的列表中,这显然是没有意义的。
您可能希望将两个参数限制为相同的列表类型:
public static <T> void copy(List<T> src, List<T> dest) {
...
}
答案 2 :(得分:0)
List<?>
等效于List<? extends Object>
,因为默认情况下,通配符位于Object
的上限。
现在,编译器出现错误,因为您无法将任何对象添加到List<?>
。
为什么?因为您不能保证它真正指向的是哪种列表。它可以是Object
的任何子类,因此不能保证在该object
中允许使用特定的List
。唯一的“保证”是您只能从中读取内容,并且可以获得Object或Object的子类。
答案 3 :(得分:0)
“通配符捕获”意味着您可以将类型List<?>
的参数传递给类型List<E>
的参数,其中E
在该方法中是通用的,并且在{ {1}}。
在这里,您没有任何通用方法,因此捕获并不重要。