This is jdk1.7.0_04.
I was attempting to use Collections.emptyList() rather than newing up my own empty list in a conditional:
List<String> list = (anArray != null) ? Arrays.asList(anArray) : Collections.emptyList();
but get the following error:
error: incompatible types
List<String> list = (anArray != null) ? Arrays.asList(anArray) : Collections.emptyList();
^
required: List<String>
found: List<CAP#1>
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ? extends Object
1 error
I was able to figure that I needed to change things to:
List<String> list = (anArray != null) ? Arrays.asList(anArray) : Collections.<String>emptyList();
But as part of working on this I encountered the bizarre (to me, anyways) situation that:
List<String> alwaysEmpty = Collections.emptyList();
compiles fine, but:
List<String> alwaysEmpty = (List<String>) Collections.emptyList();
gives the following compile error:
error: inconvertible types
List<String> alwaysEmpty = (List<String>) Collections.emptyList();
^
required: List<String>
found: List<Object>
What the heck??
Now I can understand that perhaps for some strange reason the use of the conditional operator is somehow blocking the type inference system from realizing that the type parameter for the emptyList() call should be String and so it needs to be explicitly specified. But why does inserting a (admittedly redundant) cast mess things up?
Because now the expression
Collections.emptyList()in itself isn’t the target of any assignment – so what type argument should be chosen? It’s better just to specify the type argument:It works the same for the conditional operator, too: