多个嵌套通配符 – 不适用的参数

我大大简化了我的问题。 这是它的阅读方式。

我试图弄清楚为什么以下代码无法编译:

List<AnonType<AnonType>> l = new ArrayList<AnonType<AnonType>>(); l.add( new AnonType<AnonType>() ); 

哪里

 public class AnonType { T a; List b; } 

编译器错误表示add不适用于给定的参数。 OTOH,以下代码只有1级嵌套通配符完美编译:

 List<AnonType> l = new ArrayList<AnonType>(); l.add( new AnonType() ); 

以下编译符合预期:

  List>> list = new ArrayList>>(); list.add(new HashSet>()); list.add(new HashSet>()); 

问题是generics是类型不变的。

考虑一个更简单的例子:

  • 鉴于从AnimalDog转换(例如Dog extends Animal )……
    • List 不是 List
  • List有一个捕获转换List ListList

现在这是在这种情况下发生的事情:

  • 鉴于存在从SetSet的捕获转换…
    • Set> 不是 Set>
  • Set>有一个捕获转换Set> Set>Set>

因此,如果你想要List ,你可以在其中添加Set>Set>等,那么T 不是 Set> ,而是Set> Set>

相关问题

  • 无法使用generics转换为非特定嵌套类型
  • generics方法上的多个通配符使Java编译器(和我!)非常混淆
  • Java通用List> List>
  • 任何简单的方法来解释为什么我不能做List animals = new ArrayList()
  • 之间有什么区别?

也可以看看

  • Javagenerics教程
    • generics和子类型 | 通配符 | 使用通配符更有趣
  • Angelika Langer的Java Generics FAQ
    • 什么是有界通配符?
    • generics类型的实例化中存在哪些超子类关系?

它不会编译,因为语句的Pair<,>中的第二个参数的类型是String并且该类型可能不是声明中使用的“未知”类型。 我认为如果你更换它会编译?Object 。 当然,您将失去编译时类型检查。