Pau*_*ton 21 java generics types wildcard
我试图理解java泛型,它们似乎非常难以理解.例如,这很好......
public class Main {
public static void main(String[] args) {
List<?> list = null;
method(list);
}
public static <T> void method(List<T> list) { }
}
Run Code Online (Sandbox Code Playgroud)
......这就是......
public class Main {
public static void main(String[] args) {
List<List<?>> list = null;
method(list);
}
public static <T> void method(List<T> list) { }
}
Run Code Online (Sandbox Code Playgroud)
... 还有这个 ...
public class Main {
public static void main(String[] args) {
List<List<List<?>>> list = null;
method(list);
}
public static <T> void method(List<List<T>> list) { }
}
Run Code Online (Sandbox Code Playgroud)
...但这不编译:
public class Main {
public static void main(String[] args) {
List<List<?>> list = null;
method(list);
}
public static <T> void method(List<List<T>> list) { }
}
Run Code Online (Sandbox Code Playgroud)
有人可以用简单的语言解释发生了什么吗?
Bor*_*der 14
通用类型要理解的主要问题是它们不是协变的.
所以你可以这样做:
final String string = "string";
final Object object = string;
Run Code Online (Sandbox Code Playgroud)
以下内容无法编译:
final List<String> strings = ...
final List<Object> objects = strings;
Run Code Online (Sandbox Code Playgroud)
这是为了避免您绕过泛型类型的情况:
final List<String> strings = ...
final List<Object> objects = strings;
objects.add(1);
final String string = strings.get(0); <-- oops
Run Code Online (Sandbox Code Playgroud)
所以,逐个浏览你的例子
你的通用方法需要一个List<T>,你传入一个List<?>; 这是(基本上)a List<Object>.T可以分配给Object类型,编译器很高兴.
你的通用方法是一样的,你传入一个List<List<?>>.T可以分配给List<?>类型,编译器也很高兴.
这与另一个嵌套级别的2基本相同.T仍然是List<?>那种类型.
这里是一个小梨形的地方,我从上面的点进来.
你的通用方法需要一个List<List<T>>.你传了一个List<List<?>>.现在,由于泛型类型不协变,List<?>因此无法分配给a List<T>.
实际的编译器错误(Java 8)是:
required:
java.util.List<java.util.List<T>>found:java.util.List<java.util.List<?>>reason:无法推断类型变量(s)T(参数不匹配;java.util.List<java.util.List<?>>无法转换为java.util.List<java.util.List<T>>)
基本上,编译器告诉您它无法找到T要分配的内容,因为必须推断List<T>外部列表中嵌套的类型.
让我们更详细地看一下这个:
List<?>是List的一些未知类型 -它可以是一个List<Integer>或一个List<String>; 我们可以get从它那里Object,但我们不能add.因为否则我们遇到了我提到的协方差问题.
List<List<?>>是List的List一些未知类型的-它可能是一个List<List<Integer>>或一个List<List<String>>.如果1是可以分配T到Object,只是不允许add通配符列表上的操作.在案例4中,这不可能完成 - 主要是因为没有一个泛型构造来防止add外部List.
如果编译器在第二种情况下分配T给Object那么类似下面的东西是可能的:
final List<List<Integer>> list = ...
final List<List<?>> wildcard = list;
wildcard.add(Arrays.asList("oops"));
Run Code Online (Sandbox Code Playgroud)
因此,由于协方差,不可能安全地分配List<List<Integer>>给任何其他通用List.
| 归档时间: |
|
| 查看次数: |
394 次 |
| 最近记录: |