【发布时间】:2015-07-04 16:33:21
【问题描述】:
这个问题与another one 密切相关。但是,我觉得这个问题的公认答案并不那么确定。
那么,Java 8 中方法引用的类型是是什么?下面是如何将方法引用“转换”(提升?)到java.util.function.Function 的一个小演示:
package java8.lambda;
import java.util.function.Function;
public class Question {
public static final class Greeter {
private final String salutation;
public Greeter(final String salutation) {
this.salutation = salutation;
}
public String makeGreetingFor(final String name) {
return String.format("%s, %s!", salutation, name);
}
}
public static void main(String[] args) {
final Greeter helloGreeter = new Greeter("Hello");
identity(helloGreeter::makeGreetingFor)
.andThen(g -> "<<<" + g + ">>>")
.apply("Joe");
//Compilation error: Object is not a function interface
// Function
// .identity()
// .apply(helloGreeter::makeGreetingFor)
// .andThen(g -> "<<<" + g + ">>>")
// .apply("Joe");
Function
.<Function<String,String>>identity()
.apply(helloGreeter::makeGreetingFor)
.andThen(g -> "<<<" + g + ">>>")
.apply("Joe");
//Compilation error: Cannot resolve method 'andThen(<lambda expression>)'
// (helloGreeter::makeGreetingFor)
// .andThen(g -> "<<<" + g + ">>>")
// .apply("Joe");
// java.lang.invoke.LambdaMetafactory ???
}
private static <I,O> Function<I,O> identity(final Function<I,O> fun1) {
return fun1;
}
}
那么,是否有一种不那么痛苦(更直接)的方式将方法引用转换为可以传递的编译/具体类型?
【问题讨论】:
-
Function<String, String> f = helloGreeter::makeGreetingFor;?推断方法引用的类型。相同的方法引用可以用作消费者、函数或其他功能接口,具体取决于上下文。 -
如果您觉得某个问题没有得到足够好的回答,您应该在最初的问题上提供奖励,而不是再次询问。您的问题与之前的问题有何不同,或者我可以将其作为重复项关闭吗?
-
我想,本质上,它们是相同的。虽然这里的答案似乎更具体。我会自己关闭它。
-
这个问题掩盖了一个不正确的假设:所有表达式都具有内在(自下而上)类型。方法引用和 lambda 是 poly 表达式 的示例,表达式的类型取决于其上下文。方法 ref 或 lambda 的类型只是它被分配/转换到的类型(前提是该类型与相关的 lambda/方法 ref 兼容。)
-
@Andrey 你的惊喜是错的; Java 中的每个表达式确实 都有一个具体的编译时类型。这里的新内容是,对于某些表达式,该类型可能会受到表达式出现的上下文的影响(或需要来自该上下文的类型信息),例如赋值目标类型。 Lambda 和方法 ref 有一个类型,但这不是由表达式本身决定的,而是由外部类型信息(赋值或强制转换目标类型,当然要经过适用性检查)决定。
标签: java lambda functional-programming java-8 method-reference