Java 8是否支持作为第一类对象的功能?

时间:2014-03-20 10:40:00

标签: java functional-programming

我今天读到了有关Java 8版本的内容。但我完全不了解Java 8中引用方法的概念。这是否意味着Java现在支持函数作为第一类对象?我已经看到,如何构造对函数的引用。但在我看来,他们提供的Converter对象功能非常有限。现在是否可以在Java中使用:

  • 将函数作为参数传递给另一个函数?
  • 将函数作为返回值从另一个函数返回?
  • 那么关闭呢?它们是否像功能语言一样完全实现,或者它们确实有一些限制?在我看来,有一些限制(你不能改变你在一个闭包中引用的变量的值,它必须被标记为final等等。)

4 个答案:

答案 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中的一流对象,以回答您的问题:

  1. 是的,你可以传递它,它需要满足签名。

    • 对于void method()您使用Runnable,如下所示:
      Runnable method = this::method如果它在同一个类中,然后使用method.run()运行实际方法。
    • 但对于double method(),您需要使用DoubleSupplier,如下所示: DoubleSupplier method = this::method,然后将其用作double d = method.get()
    • 还有更多签名,您甚至可以使用功能界面定义自己的签名。
  2. 是的,但是只有特定的签名,如第1点所示。

  3. Lambdas的行为完全与匿名内部类一样,它本身就是闭包,Java因为引入了匿名内部类而支持闭包。现在唯一添加的是语法更漂亮。

答案 3 :(得分:1)

不,不是一流的功能。 Lambda表达式包含在接口和some syntatic sugar applied for brevity中。

但是你可以自己创建一个函数并将它传递给不同的方法,无论这个关键点是否是另一个问题。

相关问题