Lambda expression and method overloading
Lukas Eder
lukas.eder at gmail.com
Sun May 4 07:42:02 UTC 2014
Dear EG,
This is a cross-post of my Stack Overflow question here:
http://stackoverflow.com/questions/23430854/lambda-expression-and-method-overloading-doubts
The question has reached above-average popularity on SO, so I thought I
would reach out to you for an authoritative reply. At the current stage of
Java 8 adoption, I'm afraid that there might still be a bit of speculation
from the community about such compiler issues.
Answers on lambda-dev and/or on SO would be greatly appreciated.
--------
Let's assume I have this API:
static void run(Consumer<Integer> consumer) {
System.out.println("consumer");
}
static void run(Function<Integer, Integer> function) {
System.out.println("function");
}
Using Java 8 lambda expressions, I can call the above like so:
// Consumer
run((Integer i) -> {});
// Function
run((Integer i) -> 1);
But this will not compile:
// Consumer
run(i -> {});
// Function
run(i -> 1);
I get this error message:
Test.java:63: error: reference to run is ambiguous
run(i -> {});
^
both method run(Consumer<Integer>) in Test and
method run(Function<Integer,Integer>) in Test match
I *suspect* that this is due to JLS §15.12.2:
> Certain argument expressions that contain implicitly typed
> lambda expressions (§15.27.1) or inexact method references
> (§15.13.1) are ignored by the applicability tests, because
> their meaning cannot be determined until a target type is selected.
Is that assumption true? And why were things decided this way? I'm
particularly interested in the applicability of "void-compatible" vs.
"value-compatible" expressions *might* be a more special case, as the
target type can "easily" be determined, at least in my example. Of course,
I'm certainly not seeing the big picture.
Looking forward to hearing from you,
Lukas
More information about the lambda-dev
mailing list