My overload method is overloaded with 4 different functional interfaces. I have 3 examples in which I call this overloaded method with a lambda that is compatible with 2 of those functional interfaces. In the first example the compiler understandably tells me my method call is ambiguous.
In scenario 2 and 3 however the compiler does not complain... why not?
public class AmbiguityTest {
private static void overload(Consumer<String> consumer) {
}
private static void overload(Function<String, String> function) {
}
private static void overload(Runnable runnable) {
}
private static void overload(Supplier<String> supplier) {
}
public static void testLambda1() {
//This lambda is compatible with 2 functional interfaces: Consumer<String> and Function<String, String>
//Calling the overload method gives an "ambiguous method call" error. Makes sense.
Consumer<String> consumer = ignored -> Instant.now().toString();
Function<String, String> function = ignored -> Instant.now().toString();
overload(ignored -> Instant.now().toString());
}
public static void testLambda2() {
//This lambda is also compatible with 2 functional interfaces: Consumer<String> and Function<String, String>
//Yet here calling the overload method does not give a compile time error. ???WHY NOT???
Consumer<String> consumer = (String ignored) -> Instant.now().toString();
Function<String, String> function = (String ignored) -> Instant.now().toString();
overload((String ignored) -> Instant.now().toString());
}
public static void testLambda3() {
//This lambda is compatible with 2 functional interfaces: Runnable and Supplier<String>
//Again there is no compile time error although 2 overloaded methods match. ???WHY NO AMBIGUITY???
Runnable runnable = () -> Instant.now().toString();
Supplier<String> supplier = () -> Instant.now().toString();
overload(() -> Instant.now().toString());
}
}
My overload method is overloaded with 4 different functional interfaces. I have 3 examples in which I call this overloaded method with a lambda that is compatible with 2 of those functional interfaces. In the first example the compiler understandably tells me my method call is ambiguous.
In scenario 2 and 3 however the compiler does not complain... why not?
public class AmbiguityTest {
private static void overload(Consumer<String> consumer) {
}
private static void overload(Function<String, String> function) {
}
private static void overload(Runnable runnable) {
}
private static void overload(Supplier<String> supplier) {
}
public static void testLambda1() {
//This lambda is compatible with 2 functional interfaces: Consumer<String> and Function<String, String>
//Calling the overload method gives an "ambiguous method call" error. Makes sense.
Consumer<String> consumer = ignored -> Instant.now().toString();
Function<String, String> function = ignored -> Instant.now().toString();
overload(ignored -> Instant.now().toString());
}
public static void testLambda2() {
//This lambda is also compatible with 2 functional interfaces: Consumer<String> and Function<String, String>
//Yet here calling the overload method does not give a compile time error. ???WHY NOT???
Consumer<String> consumer = (String ignored) -> Instant.now().toString();
Function<String, String> function = (String ignored) -> Instant.now().toString();
overload((String ignored) -> Instant.now().toString());
}
public static void testLambda3() {
//This lambda is compatible with 2 functional interfaces: Runnable and Supplier<String>
//Again there is no compile time error although 2 overloaded methods match. ???WHY NO AMBIGUITY???
Runnable runnable = () -> Instant.now().toString();
Supplier<String> supplier = () -> Instant.now().toString();
overload(() -> Instant.now().toString());
}
}
Share
Improve this question
asked Mar 22 at 23:19
SkifozoaSkifozoa
3233 silver badges14 bronze badges
2
|
1 Answer
Reset to default 2If more than one method is accessible and applicable, the compiler selects a method, as explained in the Java Language Specification 15.12.2.5. Choosing the Most Specific Method.
The most relevant part (IMO) for this question is
A functional interface type
S
is more specific than a functional interface typeT
for an expressione
if all of the following are true:
- . . .
- Let
MTS
be the function type of the capture ofS
, and letMTT
be the function type ofT
. ...- . . .
- Let
RS
be the return type ofMTS
, adapted to the type parameters ofMTT
, and letRT
be the return type ofMTT
. One of the following must be true:
e
is an explicitly typed lambda expression (§15.27.1), and one of the following is true:
RT
isvoid
.
As we can see, there is a differentiation between using an explicitly typed lambda (String ignored) ->
) and using an implicitly typed one (ignored ->
):
- an explicitly typed lambda returning
void
(e.g.Consumer
andRunnable
) is considered less specific than a non-void
one (Function
andSupplier
); - for implicitly typed lambda, returning
void
is not considered.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744301185a4567508.html
testLambda1
is not an explicitly typed lambda, so no more specific interface; as opposed to the other 2 tests, explicitly typed and one returningvoid
– user85421 Commented Mar 23 at 0:22