Reputation: 2770
I would like to know why the code ☆2
can be compiled with Java8
:
public class Sandbox {
public static void main(String[] args) {
// ☆1: NG: Type mismatch: cannot convert from Object to String
String res0 = IList.nil().head();
// ☆2: OK: I don't know why it's OK.
String res1 = IList.nil().head2();
}
static class IList<E> {
static <Z> IList<Z> nil() {
return null;
}
E head() {
return null;
}
<TeE extends E> TeE head2() {
return null;
}
}
}
Note: Also I am wondering that the JEP(http://openjdk.java.net/jeps/101)'s goal.
Upvotes: 1
Views: 136
Reputation: 13331
This has nothing to do with Java 8. #2 also compiles on Java 7.
I think what it all boils down to is <TeE extends E>
in your head2
method. Java sees that you're expecting a String
in return, because of this line:
String res1 = IList.nil().head2();
Therefore it concludes that, ah, in that case I'll return a String
for now - because String
extends Object
, so the <TeE extends E>
is valid.
This works thanks to the fact you're returning null inside the method. If you would not do that, an error would occur within that method. And as null can be assigned to everything but primitives, this code is OK.
Upvotes: 4
Reputation: 198033
Java typically defaults generics to their outer bound. In this particular case it types as
String res1 = IList.<Object>nil().<String>head2();
...because only the outermost method call "knows" the desired result type.
Upvotes: 4