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