I found a piece of code that after switching from Java 7 to Java 8 stopped compiling. It does not feature any of the new Java 8 stuff like lambda or streams.
I narrowed the problematic code down to the following situation:
GenericData<Double> g = new GenericData<>(1d);
Double d = g == null ? 0 : g.getData(); // type error!!!
You can probably guess that GenericData
's constructor has one parameter of that generic type and the getData()
method returns just that generic type. (For the complete source code see below.)
Now what bothers me is that in Java 7 that code compiled just fine whereas with Java 8 I get the following error:
CompileMe.java:20: error: incompatible types: bad type in conditional expression
Double d = g == null ? 0 : g.getData();
^
int cannot be converted to Double
It seems that Java 7 was able to do the transition from int -> double -> Double, but Java 8 fails with trying to immediately go from int -> Double.
What I find funny in particular is that Java 8 does accept the code when I change it from getData()
to data
, i.e. access the GenericData
's value via the variable itself instead of the getter-method:
Double d2 = g == null ? 0 : g.data; // now why does this work...
So the two questions I have here are:
- Why doesn't Java 8 infer the types like Java 7 and cast my int to double before autoboxing double to Double?
- Why does that problem only occur with the generic method but not the generic variable?
Complete source code:
public class CompileMe {
public void foo() {
GenericData<Double> g = new GenericData(1d);
Double d = g == null ? 0 : g.getData(); // type error!!!
Double d2 = g == null ? 0 : g.data; // now why does this work...
}
}
class GenericData<T> {
public T data;
public GenericData(T data) {
this.data = data;
}
public T getData() {
return data;
}
}
To test it run the compiler as follows:
javac -source 1.7 -target 1.7 CompileMe.java # ok (just warnings)
javac -source 1.8 -target 1.8 CompileMe.java # error (as described above)
Finally in case it matters: I run Windows 8 and Java 1.8.0_112 (64-bit).