用于填充不同列表的三元运算符 - 编译器错误

时间:2017-04-27 11:24:53

标签: java generics compiler-errors

当我尝试使用三元运算符来选择要添加到哪个数组列表时:

List<String> a = new ArrayList<>();
List<String> b = new ArrayList<>();

(true ? a : b).add("test");

当我尝试在三元运算符中启动列表时:

List<String> a = new ArrayList<>();

(true ? a : new ArrayList<>()).add("test");

它不适用于错误:

  

该方法在类型中添加(捕获#1-of?extends Object)   列表不适用于   arguments(String)

我不明白为什么这不合法。虽然没有意义,但以下工作正常:

(new ArrayList<>()).add("test");

我想更好地理解Java编译器及其工作原理,这就是我提出这个问题的原因。我明白这不太实际。

修改

我想了解的关键是为什么它不能在三元组中起作用,但它本身可以正常工作。

2 个答案:

答案 0 :(得分:6)

这是因为钻石符号(new ArrayList<>)使用了您的引用(List<String>)中的类型推断。

请参阅Oracle文档here

但是在第二种情况下,编译器不能/不能从三元条件的另一个术语(a的引用)推断泛型类型。

您可以使用以下成语修复它,并使用明确的通用参数:

(true ? a : new ArrayList<String>()).add("test");

答案 1 :(得分:4)

指定类型变量将解决您的问题:

(true ? a : new ArrayList<String>()).add("test");

问题是编译器无法自动检测在这种情况下要使用的类型变量,实际上是什么错误。

更具体地说,仅将new ArrayList<>()直接分配给类型参数化变量,等同于编写new ArrayList<Object>(),即它被解释为Object类型变量。