Issues with resolving overloaded methods – passing lambdas 

Let's cover the existing issues with resolving overloaded methods when lambdas are passed as method parameters. Let's define two interfaces, Swimmer and Diver, as follows:

interface Swimmer {
boolean test(String lap);
}
interface Diver {
String dive(int height);
}

In the following code, the overloaded evaluate method accepts the interfaces Swimmer and Diver as method parameters:

class SwimmingMeet {
static void evaluate(Swimmer swimmer) { // code compiles

System.out.println("evaluate swimmer");
}
static void evaluate(Diver diver) { // code compiles

System.out.println("evaluate diver");
}
}

Let's call the overloaded evaluate() method in the following code:

class FunctionalDisambiguation {
public static void main(String args[]) {
SwimmingMeet.evaluate(a -> false); // This code WON'T compile
}
}

Revisit the lambda from the preceding code:

a -> false                               // this is an implicit lambda

Since the preceding lambda expression doesn't specify the type of its input parameter, it could be either String (the test() method and the Swimmer interface) or int (the dive() method and the Diver interface). Since the call to the evaluate() method is ambiguous, it doesn't compile.

Let's add the type of the method parameter to the preceding code, making it an explicit lambda:

SwimmingMeet.evaluate((String a) -> false);         // This compiles!!

The preceding call is not ambiguous now; the lambda expression accepts an input parameter of the String type and returns a boolean value, which maps to the evaluate() method which accepts Swimmer as a parameter (the functional test() method in the Swimmer interface accepts a parameter of the String type).

Let's see what happens if the Swimmer interface is modified, changing the data type of the lap parameter from String to int. To avoid confusion, all of the code will be repeated, with the modifications in bold:

interface Swimmer {                            // test METHOD IS 
// MODIFIED
boolean test(int lap); // String lap changed to int lap

}
interface Diver {
String dive(int height);
}
class SwimmingMeet {
static void evaluate(Swimmer swimmer) { // code compiles

System.out.println("evaluate swimmer");
}
static void evaluate(Diver diver) { // code compiles
System.out.println("evaluate diver");
}
}

Consider the following code, thinking about which of the lines of code will compile:

1. SwimmingMeet.evaluate(a -> false);
2. SwimmingMeet.evaluate((int a) -> false);

In the preceding example, the code on both of the line numbers won't compile for the same reason—the compiler is unable to determine the call to the overloaded evaluate() method. Since both of the functional methods (that is, test() in the Swimmer interface and dive() in the Diver interface) accept one method parameter of the int type, it isn't feasible for the compiler to determine the method call.

As a developer, you might argue that since the return types of test() and dive() are different, the compiler should be able to infer the correct calls. Just to reiterate, the return types of a method don't participate in method overloading. Overloaded methods must return in the count or type of their parameters.

The return type of methods doesn't participate in method overloading. Overloaded methods must return in the count or type of their parameters.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.234.28