Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java ternary operator influence on generics type inference

public List<String> foo1() {     List<String> retval = bar();     if (retval == null)         return Collections.emptyList();     else         return retval; }  public List<String> foo2() {     List<String> retval = bar();     return retval == null ? Collections.emptyList() : retval; } 

Why does foo1() compiles fine whereas foo2() has an error? (to be more precise "Type mismatch: cannot convert from List<capture#1-of ? extends Object> to List<String>")

I would have thought that both functions would compile to the same bytecode, so a clever compiler should infer the correct type for emptyList()...

like image 913
Laurent Grégoire Avatar asked Jun 18 '14 15:06

Laurent Grégoire


2 Answers

Compiles for me fine in java 8.

Earlier versions of Java might need more help

return retval == null ? Collections.<String>emptyList() : retval; 

should work.

EDIT This is due to improvements in Java 8 type inference as explained here

http://openjdk.java.net/jeps/101

And here's a blog with the highlights: http://blog.jooq.org/2013/11/25/a-lesser-known-java-8-feature-generalized-target-type-inference/

like image 143
dkatzel Avatar answered Sep 24 '22 07:09

dkatzel


This is related with Type Inference from a generic method.

In case of code before ver. 8. It must be declared the type of result for this case.

return retval == null ? Collections.<String>emptyList() : retval;

Since ver. 8 notion of what is a target type has been expanded to include method arguments. So this is no longer required.

like image 43
Damian Leszczyński - Vash Avatar answered Sep 22 '22 07:09

Damian Leszczyński - Vash