Java 泛型 : assignment with nested wildcard parameters

标签 java generics type-parameter nested-generics

对于以下代码示例:

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/

相关文章:

java.lang.NoClassDefFoundError : scala/reflect/internal/Trees

java - setDefaultButton 未按预期工作

java - 通过设置 use.async.http.conduit 上下文属性来使用 CXF HttpAsyncClient

c# - 使用函数技术在 F# 中使用泛型重新实现 C# 继承

java - Java 中的通用算术

java - 如何将问题/答案对转移到 playframework 中的 View 类中?

c# - 将通用输入对象传递给方法 C#

java - 在Java中,匿名类可以声明自己的类型参数吗?

Java 使用内部类类型扩展类

scala - Scala运算符#>导致编译错误,但不会导致编译错误->为什么?