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.

+3


source to share


2 answers


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");

      

+6


source


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

.

+4


source







All Articles