当我尝试使用三元运算符来选择要添加到哪个数组列表时:
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编译器及其工作原理,这就是我提出这个问题的原因。我明白这不太实际。
修改
我想了解的关键是为什么它不能在三元组中起作用,但它本身可以正常工作。
答案 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
类型变量。