java - Lambda compatible with two functional interfaces does not give ambiguous method call error on overloaded method, why not?

My overload method is overloaded with 4 different functional interfaces. I have 3 examples in which I c

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
  • 2 Java Language Specification 15.12.2.5. Choosing the Most Specific Method ("A functional interface type S is more specific ... 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 is void ...") - testLambda1 is not an explicitly typed lambda, so no more specific interface; as opposed to the other 2 tests, explicitly typed and one returning void – user85421 Commented Mar 23 at 0:22
  • 4 @user85421 Perhaps you could post that as an answer, so that people can vote on it, and so that OP can accept it. – Dawood ibn Kareem Commented Mar 23 at 5:03
Add a comment  | 

1 Answer 1

Reset to default 2

If 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 type T for an expression e if all of the following are true:

  • . . .
  • Let MTS be the function type of the capture of S, and let MTT be the function type of T. ...
  • . . .
  • Let RS be the return type of MTS, adapted to the type parameters of MTT, and let RT be the return type of MTT. 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 is void.

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 and Runnable) is considered less specific than a non-void one (Function and Supplier);
  • for implicitly typed lambda, returning void is not considered.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744301185a4567508.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信