-
Bug
-
Resolution: Fixed
-
P3
-
9, 10, 11, 14, 15, 17
ADDITIONAL SYSTEM INFORMATION :
OS
WIndows10 2004, Debian 10.9
Java
9, 10, 11, 16, 17-ea
A DESCRIPTION OF THE PROBLEM :
If you nest methods that take a `Function<? Super T, ? Extends T>` as an argument, such as `Optional.map()` or `Stream.map()`, the compiler cannot recognize the type information of the inner method. Refer to the attached source code.
The conditions are a little more complicated.
1. Both outer and inner methods must take `java.util.function.Function` as an argument, such as `map()` or `flatMap()`. If you change the outer method to a method that takes a `java.util.function.Consumer`, such as `ifPresent()`, the issue will not occur.
2. The argument used in a `Function` in the inner `map()` must be the Generic argument of the outer `Function`. If the type of this argument is explicit, this issue will not occur. The important thing is that it must be explicit at the caller, and even if it is explicit at the callee as shown below, compilation will fail.
// Second argument is String
private static <T> T returnGeneric(T generic, String s) { return generic; }
// The error occurs even if you pass the Generic variable to the Second argument
Optional.of("").map(inner -> returnGeneric("", outer)).ifPresent(String::toString);
This issue does not occur in Java 8, nor does it occur in Java 9 or later when `-Xdiags:verbose` is added as a javac option. And the issue does not occur while coding in VSCode or IntelliJ.
REGRESSION : Last worked in version 8u291
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the attached source code.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compilation succeeds.
ACTUAL -
Compilation fails. The error message is as follows.
App.java:8: error: incompatible types: invalid method reference
.ifPresent(String::toString);
^
method toString in class String cannot be applied to given types
required: no arguments
found: Object
reason: actual and formal argument lists differ in length
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
---------- BEGIN SOURCE ----------
import java.util.Optional;
public class App {
public static void main(String[] args) {
Optional.of("").map(outer -> {
Optional.of("")
.map(inner -> returnGeneric(outer))
.ifPresent(String::toString);
return "";
});
}
private static <T> T returnGeneric(T generic) {
return generic;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Casting explicitly.
map(inner -> (String) returnGeneric(outer))
or
map(inner -> returnGeneric((String) outer))
FREQUENCY : always
OS
WIndows10 2004, Debian 10.9
Java
9, 10, 11, 16, 17-ea
A DESCRIPTION OF THE PROBLEM :
If you nest methods that take a `Function<? Super T, ? Extends T>` as an argument, such as `Optional.map()` or `Stream.map()`, the compiler cannot recognize the type information of the inner method. Refer to the attached source code.
The conditions are a little more complicated.
1. Both outer and inner methods must take `java.util.function.Function` as an argument, such as `map()` or `flatMap()`. If you change the outer method to a method that takes a `java.util.function.Consumer`, such as `ifPresent()`, the issue will not occur.
2. The argument used in a `Function` in the inner `map()` must be the Generic argument of the outer `Function`. If the type of this argument is explicit, this issue will not occur. The important thing is that it must be explicit at the caller, and even if it is explicit at the callee as shown below, compilation will fail.
// Second argument is String
private static <T> T returnGeneric(T generic, String s) { return generic; }
// The error occurs even if you pass the Generic variable to the Second argument
Optional.of("").map(inner -> returnGeneric("", outer)).ifPresent(String::toString);
This issue does not occur in Java 8, nor does it occur in Java 9 or later when `-Xdiags:verbose` is added as a javac option. And the issue does not occur while coding in VSCode or IntelliJ.
REGRESSION : Last worked in version 8u291
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the attached source code.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compilation succeeds.
ACTUAL -
Compilation fails. The error message is as follows.
App.java:8: error: incompatible types: invalid method reference
.ifPresent(String::toString);
^
method toString in class String cannot be applied to given types
required: no arguments
found: Object
reason: actual and formal argument lists differ in length
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
---------- BEGIN SOURCE ----------
import java.util.Optional;
public class App {
public static void main(String[] args) {
Optional.of("").map(outer -> {
Optional.of("")
.map(inner -> returnGeneric(outer))
.ifPresent(String::toString);
return "";
});
}
private static <T> T returnGeneric(T generic) {
return generic;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Casting explicitly.
map(inner -> (String) returnGeneric(outer))
or
map(inner -> returnGeneric((String) outer))
FREQUENCY : always
- duplicates
-
JDK-8282705 compiler cannot infer type correctly when using method reference
- Closed
-
JDK-8295988 Incorrect method reference type inference
- Closed