泛型,类型参数和通配符

泛型,类型参数和通配符,第1张

泛型,类型参数和通配符

对于泛型类型,主要要了解的是它们不是协变的。

因此,尽管您可以这样做:

final String string = "string";final Object object = string;

以下内容将无法编译:

final List<String> strings = ...final List<Object> objects = strings;

这是为了避免您绕过通用类型的情况:

final List<String> strings = ...final List<Object> objects = strings;objects.add(1);final String string = strings.get(0); <-- oops

因此,一一讲解您的示例

1个

您的通用方法采用a

List<T>
,而您采用
List<?>
;(基本上是)
List<Object>
T
可以分配给
Object
类型,并且编译器满意。

2

您的通用方法相同,您传入

List<List<?>>
T
可以分配给
List<?>
类型,编译器再次感到高兴。

3

这与 2 基本上相同,但具有另一层嵌套。

T
仍然是
List<?>
类型。

4

这是有点梨形的地方,也是我从上面提出的观点。

您的通用方法采用

List<List<T>>
。您通过了
List<List<?>>
。现在,由于通用类型不是协变的,
List<?>
因此无法将其分配给
List<T>

实际的编译器错误(Java 8)是:

必填:

java.util.List<java.util.List<T>>
找到:
java.util.List<java.util.List<?>>
原因:无法推断类型变量
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"));

因此,由于协方差,不可能安全地将a分配

List<List<Integer>>
任何其他 泛型
List



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5479027.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存