gpt4 book ai didi

java - 什么决定了从 lambda 创建哪个功能接口(interface)?

转载 作者:搜寻专家 更新时间:2023-10-31 19:53:02 25 4
gpt4 key购买 nike

请考虑这个例子:

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);
}
}

我感兴趣的是第一个测试。为什么使用 MyConsumer 而不是 Consumer ?如果我有更多具有相同 lambda 结构的不同可能消费者,谁有优先权怎么办?另外,我在测试 2 中执行的转换被我的 IDE 标记为 Redundant。这意味着首先将 lamdba 创建为 MyConsumer。为什么会这样?

我正在使用 IntelliJ Idea 和 Javac。

最佳答案

按照choosing the most specific method的流程进行由语言规范定义:

If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.

...

A functional interface type S is more specific than a functional interface type T for an 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 return type of the function type of the capture of S, and V1 ... Vk and R2 are the parameter types and return type of the function type of T):

  • If e is an explicitly typed lambda expression (§15.27.1), then one of the following is true:
  • R2 is void.

  • R1 <: R2.

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

    (The result expression of a lambda expression with a block body is defined in §15.27.2; the result expression of a lambda expression with an expression body is simply the body itself.)

  • R1 is a primitive type, and R2 is a reference type, and there is at least one result expression, and each result expression of 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 of e is either a standalone expression of a reference type or a poly expression.

  • 如果 e 是精确方法引用表达式(§15.13.1),则 i) 对于所有 i (1 ≤ i ≤ k),Ui 与 Vi 相同,并且 ii) 以下之一为真:
  • R2 is void.

  • R1 <: R2.

  • R1 is a primitive type, R2 is a reference type, and the compile-time declaration for the 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 the method reference has a return type which is a reference type.

  • 如果 e 是带括号的表达式,则这些条件之一递归地应用于包含的表达式。

  • 如果 e 是条件表达式,则对于第二个和第三个操作数中的每一个,递归地应用其中一个条件。

因此,MyConsumerConsumer 更具体,因为 Consumer(规范中的 T)不是子类型,两者都有 void 的返回值。

关于java - 什么决定了从 lambda 创建哪个功能接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41981693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com