SPI*_*984 8 java functional-programming
我今天读到了有关Java 8版本的内容.但我完全不了解Java 8中引用方法的概念.这是否意味着Java现在支持函数作为第一类对象?我已经看到,如何构造对函数的引用.但在我看来,他们提供的Converter对象功能非常有限.它现在可以在Java中使用:
有可能的。你怎么做呢?
首先构造一个“功能接口”(或使用提供的接口之一)。函数式接口是具有单一方法的接口。java.lang.Runnable 就是一个例子。
其次,编写一个以函数式接口作为参数的方法。
public void doAThing(Runnable r) {
r.run();
}
Run Code Online (Sandbox Code Playgroud)
第三,编写具有正确签名的方法。
public class MyClass {
public void runAThing() {
System.out.println("I executed!");
}
}
Run Code Online (Sandbox Code Playgroud)
第四,调用传入方法引用的函数。
MyClass mc = new MyClass();
doAThing(mc::runAThing);
Run Code Online (Sandbox Code Playgroud)
您会注意到您编写的所有类都没有显式实现Runnable
. 这是由编译器为您处理的。
您可以使用 lamdba 表达式执行类似的操作:
doAThing(() -> System.out.println("I executed as a lamdba expression!"));
Run Code Online (Sandbox Code Playgroud)
要将函数作为另一个函数的值返回,只需返回 的实例Runnable
。
第一类函数最重要的方面已经融入现有的Java类型系统中.没有引入真正的函数类型 ; 任何单方法接口都是它自己的"函数类型".因此,对于前两个问题,您可以自由地传递这些功能接口的实例.
语义有许多细微的变化,允许使用lambda语法/方法引用来实现任何这样的接口.您甚至可以使用高阶函数,例如compose
返回泛型Function
类型的函数,并将其传递给期望兼容的函数接口类型的方法.
您无法更改在闭包中引用的变量的值
这不是Java特有的限制.实际上,大多数FP语言都不支持任何类型的可变变量.请注意,不要求final
在变量上使用关键字; 有效最终的概念照顾到了这一点.
除了反射中已经存在的用法之外,方法并不是 Java 中的一流对象,来回答您的问题:
是的,可以传递,但是需要满足签名。
void method()
您可以使用 a Runnable
,如下所示:Runnable method = this::method
如果它位于同一个类中,则使用 运行实际方法method.run()
。double method()
您需要使用 a DoubleSupplier
,如下所示:
DoubleSupplier method = this::method
,然后将其用作double d = method.get()
。是的,这是可能的,但仅限于第 1 点中所示的特定签名。
Lambda 的行为与匿名内部类完全相同,匿名内部类本身就是闭包,Java 自从引入匿名内部类以来就支持闭包。现在唯一添加的是语法更加漂亮。