What determines which functional interface to create from lambda?

Please consider this example:

import java.util.function.Consumer; public class Example { public static void main(String[] args) { Example example = new Example(); example.setConsumer(test -> System.out.println("passed string is " + test)); //uses MyConsumer, why ? example.getConsumer().accept("Test 1"); example.setConsumer((MyConsumer<String>)test -> System.out.println("passed string is " + test)); //uses MyConsumer example.getConsumer().accept("Test 2"); example.setConsumer((Consumer<String>)test -> System.out.println("passed string is " + test)); //uses Consumer example.getConsumer().accept("Test 3"); } private Consumer<String> consumer; public Consumer<String> getConsumer() { return consumer; } public void setConsumer(Consumer<String> consumer) { this.consumer = consumer; } public void setConsumer(MyConsumer<String> consumer) { this.consumer = consumer; } @FunctionalInterface public interface MyConsumer<T> extends Consumer<T> { @Override default void accept(T value) { System.out.println("In consumer string: " + value); //example thing to do receive(value); } void receive(T value); } } 

I'm interested in the first test. Why does he use MyConsumer instead of Consumer? What if I had more different Consumers with the same lambda structure who have priority? Also, the listing I'm doing on Test 2 is marked as Redundant my IDE. This means that lamdba is first created as MyConsumer. Why is that?

I am using IntelliJ Idea with Javac.

+5
source share
1 answer

In accordance with the procedure, choosing the most specific method , as determined by the language specification:

If more than one member method is available and applicable to a method call, you must select it to provide a handle to send the runtime. The Java programming language uses a rule in which the most specific method is selected.

...

The type of the functional interface S is more specific than the type of the functional interface T for the expression e, if T is not a subtype of S, and one of the following is true (where U1 ... Uk and R1 are the parameter types and the return type of the capture function type S, and V1 ... Vk and R2 are the parameter types and the return type of the function type T):

  • If e is an explicitly typed lambda expression (ยง15.27.1), then one of the following statements holds:
  • R2 is invalid.

  • R1 <: R2.

  • R1 and R2 are functional types of interfaces, and there is at least one expression of the result, and R1 is more specific than R2 for each expression of the result of e.

    (The result of expressing a lambda expression with a block body is defined in ยง 15.27.2, the expression of the result of a lambda expression with the body of the expression is just the body).

  • R1 is a primitive type, and R2 is a reference type, and there is at least one result expression, and each result expression e is a standalone expression (ยง15.2) of a primitive type.

  • R1 is a reference type, and R2 is a primitive type, and there is at least one result expression, and each result expression e is either a standalone expression of a reference type or a poly-expression.

  • If e is the exact reference expression of the method (ยง15.13.1), then i) for all i (1 โ‰ค i โ‰ค k), Ui coincides with Vi and ii) one of the following conditions is true: / li>
  • R2 is invalid.

  • R1 <: R2.

  • R1 is a primitive type, R2 is a reference type, and the compilation time declaration for a method reference has a return type, which is a primitive type.

  • R1 is a reference type, R2 is a primitive type, and the compile-time declaration for a method reference has a return type, which is a reference type.

  • If e is an expression in parentheses, then one of these conditions is applied recursively to the contained expression.

  • If e is a conditional expression, then for each of the second and third operands one of these conditions is applied recursively.

Therefore, MyConsumer more specific than Consumer , because Consumer ( T in the specification) is not a subtype, and both have a void return value.

+6
source

Source: https://habr.com/ru/post/1263676/


All Articles