> 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)在语法方面有什么区别?
解决方法
BGGA提案
BGGA提案创建一个函数类型的概念,其中函数具有类型参数列表,返回类型和throws子句.在BGGA提案中,平方和代码看起来像清单9中的代码:
清单9.使用BGGA关闭语法计算平方和
sumOfSquares = mapReduce(myBigCollection,{ Double x => x * x },{ Double x,Double y => x + y });
左边的大括号内的代码为=>符号标识参数的名称和类型;右边的代码表示正在定义的匿名函数的实现.该代码可以引用在块内定义的局部变量,闭包的参数或创建闭包的范围的变量.
在BGGA提案中,您可以声明变量,方法参数和作为函数类型的方法返回值.您可以在任何需要单个抽象方法类的实例(如Runnable或Callable)的情况下提供闭包;对于匿名类型的闭包,提供了一个invoke()方法,以便您可以使用指定的参数列表来调用它们.
BGGA提案的主要目标之一是允许程序员创建像控制结构一样的方法.因此,BGGA还提出了一些语法糖,以允许您调用接受闭包的方法,就像它们是新的关键字一样,以便您可以创建类似于Lock()或forEach()的方法,并像调用它们一样是控制原语.清单10显示了如何根据BGGA提案定义withLock()方法;清单11和清单12显示了如何使用标准表单和“控件构造”形式来调用它们:
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(); } }
清单10中的withLock()方法接受一个锁和一个闭包.闭包的返回类型和throws子句是通用参数;编译器中的类型推断通常允许调用它,而不指定T和E的值,如清单11和清单12所示:
清单11.调用withLock()
withLock(lock,{=> System.out.println("hello"); });
清单12.使用控制构造简写调用withLock()
withLock(lock) { System.out.println("hello"); }
像仿制药一样,BGGA提案下关闭的大部分复杂性都由图书馆创作者承担;使用接收闭包的库方法要简单得多.
BGGA提案也用于修复在尝试使用内部类实例以获得关闭的好处时出现的一些透明度故障.例如,在代码块中的return,break和this的语义与代表同一代码块的Runnable(或其他内部类实例)不同.迁移代码以利用通用算法时,这些不透明的元素可能会导致混乱.
CICE的提案
CICE提议是一个更简单的提案,解决实例化内部类实例太麻烦的问题.而不是创建一个函数类型的概念,它只需创建一个更紧凑的语法,用一个抽象方法(如Runnable,Callable或Comparator)来实例化内部类的实例.
清单13显示了CICE下的平方和代码的总和.它显示了mapReduce()使用的UnaryFunction和BinaryFunction类型. mapReduce()的参数是从UnaryFunction和BinaryFunction派生的匿名类;该语法简单地消除了与创建匿名实例相关联的大量冗余.
Double sumOfSquares = mapReduce(myBigCollection,UnaryFunction<Double>(Double x) { return x*x; },BinaryFunction<Double,Double>(Double x,Double y) { return x+y; });
因为表示传递给mapReduce()的函数的对象是普通的匿名类实例,所以它们的主体可以引用在包围范围中定义的变量;清单13和清单7中的方法之间的唯一区别是语法的冗长度.