泛型不兼容类型

5

我遇到了不兼容的类型错误,但我并不理解原因。

这段代码为什么是错的?

List<List<String>> a = new ArrayList<>();
List b = a; // is ok
List<List> c = a; // incompatible types
4个回答

7

这里描述了这个。 超类型兼容性仅适用于“外部”级别,而不是跨类型参数“内部”。 这并不直观,但这就是它的工作原理... 此外,List是一个原始类型,并且其行为与List<Object>略有不同-这在这里中有所说明。


3
List<List> 

隐式指定的

List<List<Object>>

不是

的父级。

List<List<String>>

在第一种情况下成功的原因是因为类型推断。编译器会基本上检查表达式需要哪种类型才能有意义,并生成相应的代码。

List<List<String>> a = b;

在第二种情况下,它将默认为


List<List<Object>> a = b // which does not compile

我明白了,但为什么第二行不会在编译时出错呢?因为它可能导致与第三行相同的运行时错误。 - Alex Orlov
这正是为什么你应该优先选择泛型而不是原始类型的原因。在这种情况下,泛型代码可以保证类型安全性,而原始代码则不能。 - Seb

3
写作
List b = a;

不涉及泛型。它定义了一个名为b的原始List类型,可以将任何对象作为其元素。

不要将其与...进行比较

List<List> c = a;

由于涉及到泛型,因此编译器会在这里强制进行类型兼容性检查。


是的,但如果在代码中进一步调用b.add(new Object());,它将抛出运行时错误,因为我们基本上会执行a.add(new Object())。我的问题是,为什么第三行可以通过在编译时给出错误来防止意外错误,而第二行却不能。 - Alex Orlov
那个运行时错误与我们讨论的类型兼容性检查无关。 - Vaibhav Raj

2
简短回答:因为你的 c 列表包含各种对象的列表。
例如,您还可以添加 Integer 对象。
a 列表只能包含 String 对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接