java - Java闭包-三个主要建议之间的语法差异?

标签 java closures java-7 inner-classes bgga

提出了将closures添加到Java语言的三个主要建议:

  • BGGA (Bracha Gafter Gosling Ahé)也称为“完全关闭”,作者Gilad Bracha,Neal Gafter,James Gosling和Peter von derAhé
  • CICE (Concise Instance Creation Expressions)也称为“简化的内部类”,作者是Bob Lee,Doug Lea和Josh Bloch。
  • FCM (First Class Methods),作者:Stephen Colebourne和Stefan Schulz

  • 我的问题:
  • 这三个建议(BGGA,CICE和FCM)在语法方面有什么区别?
  • 最佳答案

    This IBM paper很好地说明了BGGA和CICE之间的语法差异:

    BGGA提案

    BGGA建议创建函数类型的概念,其中函数具有类型化的参数列表,返回类型和throws子句。在BGGA提案中,平方和代码类似于 list 9中的代码:

    list 9 。使用BGGA闭合语法计算平方和

    sumOfSquares = mapReduce(myBigCollection, 
                             { Double x => x * x }, 
                             { Double x, Double y => x + y });
    

    =>符号左侧大括号内的代码标识参数的名称和类型。右边的代码表示所定义的匿名函数的实现。该代码可以引用在块中定义的局部变量,闭包的参数或创建闭包的作用域中的变量。

    在BGGA提案中,您可以声明属于函数类型的变量,方法参数和方法返回值。您可以在需要单个抽象方法类实例(例如Runnable或Callable)的任何上下文中提供闭包;对于匿名类型的闭包,提供了invoke()方法,因此您可以使用指定的参数列表来调用它们。

    BGGA提案的主要目标之一是允许程序员创建类似于控件结构的方法。因此,BGGA还提出了一些语法糖,使您可以调用接受闭包的方法,就像它们是新的关键字一样,以便您可以创建诸如withLock()或forEach()之类的方法,并像控制原语一样调用它们。 list 10显示了如何在BGGA建议下定义withLock()方法。 list 11和 list 12展示了如何使用标准形式和“控件构造”形式来调用它:

    list 10 。在BGGA闭包提议下编码withLock()方法
    public static <T,throws E extends Exception>
    T withLock(Lock lock, {=>T throws E} block) throws E {
        lock.lock();
        try {
            return block.invoke();
        } finally {
            lock.unlock();
        }
    }
    

    list 10中的withLock()方法接受一个锁和一个闭包。闭包的返回类型和throws子句是​​通用参数;编译器中的类型推断通常允许在不指定T和E值的情况下调用它,如 list 11和 list 12所示:

    list 11 。调用withLock()
    withLock(lock, {=>
        System.out.println("hello");
    });
    

    list 12 。使用控件构造速记调用withLock()
    withLock(lock) {
        System.out.println("hello");
    }
    

    像泛型一样,BGGA提案中的闭包的大部分复杂性是由库创建者承担的。使用接受闭包的库方法要简单得多。

    BGGA提案还致力于修复尝试使用内部类实例以获得闭包的好处时出现的许多透明性失败。例如,代码块中的return,break和this的语义与代表同一代码块的Runnable(或其他内部类实例)中的语义不同。当迁移代码以利用通用算法时,这些不透明的元素会引起困惑。

    CICE提案

    CICE提案是一个更简单的提案,它解决了实例化内部类实例太麻烦的问题。它没有创建函数类型的概念,而是仅创建了一种更紧凑的语法来使用单个抽象方法(例如Runnable,Callable或Comparator)实例化内部类的实例。

    list 13显示了CICE下平方和代码的样子。它明确显示了mapReduce()使用的UnaryFunction和BinaryFunction类型。 mapReduce()的参数是从UnaryFunction和BinaryFunction派生的匿名类。该语法只是消除了与创建匿名实例相关的许多冗余。

    list 13 。 CICE关闭提案下的平方和代码
    Double sumOfSquares = mapReduce(myBigCollection,
        UnaryFunction<Double>(Double x) { return x*x; },
        BinaryFunction<Double, Double>(Double x, Double y) { return x+y; });
    

    因为表示传递给mapReduce()的函数的对象是普通的匿名类实例,所以它们的主体可以引用在封闭范围内定义的变量; list 13和 list 7中的方法之间的唯一区别是语法的冗长性。

    关于java - Java闭包-三个主要建议之间的语法差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1799196/

    相关文章:

    java - RxJava/RxAndroid - 处理多个 EditText 更改

    java - 在大型 CSV 中查找行的最简单、最快的方法

    javascript - 这是否符合 Javascript 闭包的条件?

    java - 三元条件运算符中的不兼容类型

    java - 确定编译时多捕获异常类型

    java - 如何在大型单词列表(词汇表)中查找具有下降内存消耗和查找时间的单词?

    java - 正则表达式除了第一个

    Swift,如何传递多种类型的闭包?

    swift - 在 Swift 中使用@discardableResult 作为闭包

    java - 推土机 : String-To-Date Field Level Mapping for a List