And*_*rey 4 java lambda functional-programming java-8 method-reference
这个问题与另一个问题密切相关.但是,我觉得这个问题的公认答案并不是那么明确.
那么,什么是 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;
}
}
Run Code Online (Sandbox Code Playgroud)
那么,是否有一种不那么痛苦(更直接)的方法将方法引用转换为可以传递的编译/具体类型?
首先,方法引用"是已经有名称的方法的紧凑,易于读取的lambda表达式"(参见Java教程 - 方法参考).
所以实际上,你要求的是lambda表达式的类型.这在JLS§15.27.3(Lambda表达式的类型)中清楚地解释.
简而言之,提到了三种兼容性:
lambda表达式或方法引用的类型由编译器推断.由于现在可以(并且必须)考虑几个上下文,因此Java 8对类型推断进行了大量增强.
lambda表达式的唯一限制是推断类型必须是功能接口.实际上,相等的lambda表达式在其上下文中可以具有不同的类型.
如果T是函数接口类型(第9.8节),并且表达式与从T派生的地面目标类型的函数类型一致,则方法引用表达式在赋值上下文,调用上下文或具有目标类型T的转换上下文中是兼容的.
...
如果方法引用表达式与目标类型T兼容,则表达式的类型U是从T派生的地面目标类型.
基本上,方法引用的类型是上下文所期望的.独立于上下文,方法引用实际上没有类型.没有办法传递"原始"方法引用,然后将其转换为函数或消费者或稍后的任何内容.
方法引用只是使用传递参数作为输入参数的函数的语法糖.所以,你可以用这种方式分配它们:
Runnable runnable = System.out::println;
Consumer consumer = System.out::println;
Run Code Online (Sandbox Code Playgroud)
类型是推断的并且取决于上下文.
你的情况:
Function<String, String> foo = helloGreeter::makeGreetingFor;
Run Code Online (Sandbox Code Playgroud)
它等于:
Function<String, String> foo = s -> helloGreeter.makeGreetingFor(s);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2040 次 |
| 最近记录: |