Ternary operator used to populate different lists - compiler error
When I try to use the ternary operator to select which list of arrays added to it works:
List<String> a = new ArrayList<>();
List<String> b = new ArrayList<>();
(true ? a : b).add("test");
When I try to run a list in ternary statement:
List<String> a = new ArrayList<>();
(true ? a : new ArrayList<>()).add("test");
It fails with error:
Method add (capture # 1-of? Extends Object) on type List not applicable for Arguments (String)
I don't understand why this is not legal. Although pointless, the following works great:
(new ArrayList<>()).add("test");
I want to better understand the Java compiler and how it works, which is why I am asking the question. I understand that this is not very practical.
Edit:
The key thing I'd like to understand is why it doesn't work in triple form, but works fine on its own.
source to share
This is because diamond ( new ArrayList<>
) notation uses type inference from your reference ( List<String>
).
See Oracle documentation here .
However, in the second case, the compiler cannot / is not designed to deduce a generic type from another ternary state term ( a
reference).
You can fix this by using the following idiom with a generic explication parameter:
(true ? a : new ArrayList<String>()).add("test");
source to share
Specifying the type variable will solve your problem:
(true ? a : new ArrayList<String>()).add("test");
The problem is that the compiler cannot automatically determine which type variable to use in this case, which is what the error says.
More specifically, simply new ArrayList<>()
without a direct assignment, its parameterized variable is the equivalent of a record new ArrayList<Object>()
, that is, it is interpreted as a type variable Object
.
source to share