[英]With Java, is it acceptable to use an unbounded wildcard type as a method's argument, and then check and cast it to a parameterized type?
[英]wildcard capturing java method argument and parameter type
我正在阅读Maurice Naftalin撰写的Java generics and collections
仿制品Java generics and collections
。
在关于通配符捕获的部分中,作者举了一个例子
public static void reverse(List<?> list) {
rev(list);
}
private static <T> void rev(List<T> list) {
List<T> tmp = new ArrayList<T>(list);
for (int i = 0; i < list.size(); i++) {
list.set(i, tmp.get(list.size()-i-1));
}
}
但我认为类型List<T>
是List<?>
的子类型(其中List<?>
是List<? extends Object>
的简写语法)(我的List<T>
假设是List<? extends Object>
的子类型List<? extends Object>
甚至是正确的?),所以在reverse
方法中,我们如何将变量list
( List<? extends Object>
)传递给rev
方法,其中rev
方法的参数是List<T>
类型?
我们如何将变量列表(类型为
List<? extends Object>
)传递给rev方法
你不是。
每个列表都有一个类型:你不能创建一个new ArrayList<?>
或一个new ArrayList<? extends String>
new ArrayList<? extends String>
。 您可以创建一个new ArrayList<String>
,并将其分配给具有通配符类型的变量。
因此,您可以调用List<T>
的方法,即使使用List<?>
作为参数,只要编译器可以推断出某些类型与边界一致即可。 你不知道类型,但编译器可以。
但我认为类型
List<T>
是List<?>
的子类型
事实并非如此:请记住,Java中的泛型是不变的 。 这意味着即使X是Y的子类型, List<X>
也不会是List<Y>
的子类型。
代码示例的工作原因是reverse
方法匹配任何List
类型,甚至是原始类型。
在这个声明中:
private static <T> void rev(List<T> list) {...}
T
是一种方法参数化类型,没有显式绑定指的是任何类型。
你可以在方法中传递一个声明为List<? extends Object>
的变量List<? extends Object>
List<? extends Object>
, List<?>
甚至List<String>
因为它接受List
任何类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.