对于以下代码示例:
public static class Abc<X> { }
public static class Def<Y> { }
public static class Ghi<Z> { }
public void doThis() {
List<?> listOne;
List<Abc<?>> listTwo;
List<Abc<Def<?>>> listThree;
List<Abc<Def<Ghi<?>>>> listFour;
List<Abc<Def<Ghi<String>>>> listFive;
Abc<Def<Ghi<String>>> abcdef;
abcdef = new Abc<Def<Ghi<String>>>();
listOne.add(abcdef); // line 1
listTwo.add(abcdef); // line 2
listThree.add(abcdef); // line 3
listFour.add(abcdef); // line 4
listFive.add(abcdef); // line 5
}
第 1、3 和 4 行不编译:
(第 1 行)
The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (Abc<Def<Ghi<String>>>)
(第 3 行)
The method add(Abc<Def<?>>) in the type List<Abc<Def<?>>> is not applicable for the arguments (Abc<Def<Ghi<String>>>)
(第 4 行)
The method add(Abc<Def<Ghi<?>>>) in the type List<Abc<Def<Ghi<?>>>> is not applicable for the arguments (Abc<Def<Ghi<String>>>)
然而,第 2 行和第 5 行编译。
谁能解释为什么第 1、3 和 4 行不是合法赋值?如果不能在这些行上以这种方式使用通配符参数,那么为什么第 2 行的赋值是合法的?
最佳答案
listOne.add(abcdef)
(第 1 行)无效,因为 List<?>
表示一些未知特定类型的列表。例如,它可能是 List<String>
, 所以我们不想添加任何不是 String
的东西.编译器错误发生是因为 Abc<Def<Ghi<String>>>
不可分配给 ?
.
listTwo.add(abcdef)
(第 2 行)是有效的,因为 List<Abc<?>>
表示 Abc
的列表任何类型。没错 - 嵌套 通配符与顶级通配符的不同之处在于它们代表任何类型而不是某种特定类型(换句话说,嵌套通配符不代表 capture )。编译器允许它因为 Abc<Def<Ghi<String>>>
可分配给 Abc<?>
.有关嵌套通配符的进一步讨论,请参阅此帖子:Multiple wildcards on a generic methods makes Java compiler (and me!) very confused
listThree.add(abcdef)
(第 3 行)无效,因为 List<Abc<Def<?>>>
表示 Abc
的列表的 Def
任何类型的。泛型不是协变的,所以 Abc<Def<Ghi<String>>>
不可分配给 Abc<Def<?>>
, 即使 Def<Ghi<String>>
可分配给 Def<?>
. List<Integer>
不可分配给 List<Number>
出于同样的原因。有关详细说明,请参阅此帖子:Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?
listFour.add(abcdef)
(第 4 行)由于同样的原因无效 - Abc<Def<Ghi<String>>>
不可分配给 Abc<Def<Ghi<?>>>
.
listFive.add(abcdef)
(第 5 行)是有效的,因为泛型类型完全匹配 - Abc<Def<Ghi<String>>>
显然可以分配给 Abc<Def<Ghi<String>>>
.
关于Java 泛型 : assignment with nested wildcard parameters,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24308408/