Java8中的方法引用有具体类型吗?如果有,是什么类型?
这个问题与我们的关系非常密切。然而,我觉得这个问题的公认答案并不那么确定 那么,Java8中方法引用的类型是什么?下面是如何将方法引用“转换”(提升?)到Java8中的方法引用有具体类型吗?如果有,是什么类型?,java,lambda,functional-programming,java-8,method-reference,Java,Lambda,Functional Programming,Java 8,Method Reference,这个问题与我们的关系非常密切。然而,我觉得这个问题的公认答案并不那么确定 那么,Java8中方法引用的类型是什么?下面是如何将方法引用“转换”(提升?)到java.util.function.function中的一个小演示: package java8.lambda; import java.util.function.Function; public class Question { public static final class Greeter { private fin
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;
}
}
包java8.lambda;
导入java.util.function.function;
公开课问题{
公共静态末班迎宾员{
私人最后的弦乐敬礼;
公共迎宾员(最后的弦乐敬礼){
这个。敬礼=敬礼;
}
公共字符串makeGreetingFor(最终字符串名){
返回字符串。格式(“%s,%s!”,称呼,名称);
}
}
公共静态void main(字符串[]args){
最终迎宾员helloGreeter=新迎宾员(“你好”);
标识(helloGreeter::makeGreetingFor)
.然后(g->“”)
.申请(下称“乔”);
//编译错误:对象不是函数接口
//作用
//.identity()
//.apply(helloGreeter::makeGreetingFor)
//.然后(g->“”)
//.申请(下称“乔”);
作用
.identity()
.apply(helloGreeter::makeGreetingFor)
.然后(g->“”)
.申请(下称“乔”);
//编译错误:无法解析方法“andThen()”
//(helloGreeter::makeGreetingFor)
//.然后(g->“”)
//.申请(下称“乔”);
//java.lang.invoke.LambdaMetafactory???
}
专用静态函数标识(最终函数fun1){
返回fun1;
}
}
那么,有没有一种不那么痛苦(更直截了当)的方法将方法引用强制转换为可传递的编译/具体类型?对于使用传递的参数作为输入参数的函数来说,方法引用只是一种语法糖。因此,您可以通过以下方式分配它们:
Runnable runnable = System.out::println;
Consumer consumer = System.out::println;
类型是推断的,并且依赖于上下文
你的情况:
Function<String, String> foo = helloGreeter::makeGreetingFor;
函数foo=helloGreeter::makeGreetingFor;
它等于:
Function<String, String> foo = s -> helloGreeter.makeGreetingFor(s);
函数foo=s->helloGreeter.makeGreetingFor(s);
首先,方法引用“对于已经有名称的方法,是紧凑、易于阅读的lambda表达式”(请参阅)
事实上,您要求的是lambda表达式的类型。这一点在本文中有明确的解释
简而言之,提到了三种兼容性:
基本上,方法引用的类型是上下文所期望的类型。独立于上下文,方法引用实际上没有类型。没有办法传递一个“原始”方法引用,然后在以后的某个时候将其转换为函数或使用者或任何东西。如果您只有一个方法引用
helloGreeter::makeGreetingFor
,它就没有类型
如果要为方法引用指定类型而不将其赋值或作为参数传递(将其赋值给参数),可以强制转换它:
String greeting =
((Function<String, String>)helloGreeter::makeGreetingFor)
.apply("Joe");
字符串问候语=
((函数)helloGreeter::makeGreetingFor)
.申请(下称“乔”);
函数f=helloGreeter::makeGreetingFor代码>?将推断方法引用的类型。相同的方法引用可以用作使用者、函数或其他函数接口,具体取决于上下文。如果您觉得某个问题的回答不够好,您应该对原始问题给予奖励,而不是第二次提问。你的问题与前面的问题有什么不同吗?或者我可以把它作为一个副本来结束吗?我想,本质上,它们是一样的。虽然这里的答案似乎更具体。这个问题掩盖了一个错误的假设:所有表达式都有一个内在的(自下而上的)类型。方法引用和lambda是poly表达式的示例,poly表达式的类型取决于它们的上下文。方法引用或lambda的类型仅仅是它被分配/转换到的类型(前提是该类型与所讨论的lambda/方法引用兼容)。@Andrey您的惊讶是错误的;Java中的每个表达式都有一个具体的编译时类型。这里的新功能是,对于某些表达式,该类型可能受表达式出现的上下文的影响(或需要来自该上下文的类型信息),例如赋值目标类型。lambda和method refs有一个类型,但这不是由表达式本身决定的,而是由外部类型信息决定的(赋值或强制转换目标类型,当然要经过适用性检查)。