This question already has an answer here:
Does anybody understand why the following code will compile fine in Java 7 and below, but fails with Java 8.
public static void main(String[] args) throws Exception {
put(get("hello"));
}
public static <R> R get(String d) {
return (R)d;
}
public static void put(Object o) {
System.err.println("Object " + o);
}
public static void put(CharSequence c) {
System.err.println("CharSequence " + c);
}
public static void put(char[] c) {
System.err.println("char[] " + c);
}
The get method has a generic return type. In JDK 7 and below this compiles fine and the put method with the Object parameter is chosen. In JDK 8 this cannot be compiled, indicating the put method is ambiguous.
Apparently JDK 8 is skipping over the Object-parameter method and finding the last two sub-Object-parameter methods and complaining about them (i.e. if you add another put method with some other parameter type, the compiler will switch and complain about the new last two methods)
This seems like a bug.
Your problem is a side-effect of Generalized Target-type Inference, an improvement in Java 8.
What is Target-type Inference
Let's take your example method,
Now, in the method above, the generic parameter
R
cannot be resolved by the compiler because there's no parameter withR
.So, they introduced a concept called
Target-type Inference
, which allows the parameter to be inferred based on the assignment parameter.So, if you do,
This works well in Java 7. But the following does not,
Because type inference worked only for direct assignments.
If there's no direct assignment, then the generic type was inferred as
Object
.So, when you compiled the code with Java 7, your
put(Object)
method was called without any problems.What they did in Java 8
They improved the type inference to infer the type from method calls and chained method calls
More details about them here and here
So now, you can directly call
put(get("something"))
and the generic type will be inferred based on the parameter of theput()
method.But as you know, the methods,
put(Charsequence)
andput(char[])
match the arguments. So there's the ambiguity.Fix?
Just tell the compiler exactly what you want,
Looks like this is a known incompatibility.
See "Area: Tools / javac" section of this article. And this bug.