lambda 匿名内部类_从内部投影Lambda。 布莱恩·格茨专访

lambda 匿名内部类

正如InfoQ报道的那样 ,Oracle在今年四月宣布将备受期待的Java 8的发布推迟到2014年第一季度。

OracleJava平台组首席架构师Mark Reinhold在他的博客中说:

“超越M6的最重要的工作与Lambda项目有关,这是该版本的唯一驱动功能。

我们在去年年底集成了Lambda的语言和VM更改,但是在涉及的所有活动部件和安全工作之间,花费的时间比预期的要长一点,从而使流API和相关的核心库增强功能获得了画龙点睛的一笔。”

InfoQ向Oracle的JSR-335规格负责人Brian Goetz谈到了他从内部观察到的Lambda项目。

InfoQ:从并行集合到新的Stream API,该项目需要大量协调。 在不泄露任何秘密的情况下,您能否从内部人员的角度给我们一些有关JSR-335项目的见解? 如何管理所有协调?

Brian:的确,活动部件之间的交互数量令人生畏,而且存在大量离散的利益相关者:两个互锁的专家组列表(一个纯粹用于语言功能,一个更大的列表,包括JSR-166 EG的成员)库功能),OpenJDK社区以及Oracle Java平台组内的多个组件团队。 但是回报值得。 与早期的平台开发工作不同,我们必须通过编译器中的语法糖来实现所有功能,而JSR-335能够进行语言,库和虚拟机(VM)的协同协同进化,从而产生了更好的结果总体结果。

我认为,成功的关键是保持对目标的明确关注。 语言功能并不是他们自己的目标; 语言功能是促成因素,鼓励或劝阻某些样式和习语。 即使在“添加lambda表达式”类别中,通常也存在限制该方法的隐藏目标。 BGGA提案的基本目标是通过库支持控件抽象。 CICE更加注重减轻内部类的句法痛苦的更为适度的目标。 当向C#中添加lambda时,许多用例是由LinQ的需求决定的。

对于JSR-335的努力,我们一直明确关注语言功能主要是改善图书馆的一种手段,例如对现有馆藏进行批量数据并行操作。 语言功能使图书馆更好; 更好的库可实现更简单,更清晰,更少出错的用户代码。 因此,我们收集了想要启用的用户惯用语的目录,例如对集合的批量数据并行操作,例如:

int sumOfWeights =
      anArrayList.parallelStream()
                          .filter(b -> b.getColor() == BLUE)
                          .mapToInt(b -> b.getWeight())
                          .sum();
我们将这些示例用作试金石,以确保我们朝着自己的目标迈进,而不仅仅是朝着目标迈进。
在这个简单的例子中隐含的是:
  • 需要对表达式中的行为进行紧凑编码(作为数据编码)
  • 需要将迭代控制从客户端(使用诸如for循环之类的语言功能)转移到库(内部迭代)
  • 需要向现有类型(如List.parallelStream)添加新方法(接口演化)
  • 需要更大的类型推断(以便编译器可以推断lambda形式的类型)
  • 需要能够对*非线程安全*数据结构执行并行操作

进行较大的语言功能的最大挑战之一是功能蔓延的风险。 当您已经在进行重大更改时,总是有诱惑力让其他人潜入其中。 (我们从社区那里收到了数百条建议,并且几乎对所有建议都拒绝。)对于这项工作的目的有一套清晰的目标,对于能够说“可能很酷,但这超出了范围。”

另一个关键的协调工具是在语言功能设计中使用形式数学模型,例如默认方法或类型推断行为的继承规则。 自然语言特别不适合讨论此类复杂问题。 形式模型的使用使我们能够以精确,明确的方式讨论和理解所提议功能的语义,并为规范,实现和测试提供了蓝图。

InfoQ:看来Lambda项目的大部分活动都在OpenJDK中进行。 社区参与度如何提高?

Brian:在lambda-dev邮件列表中,我们有一批专门的早期采用者,他们会定期下载最新版本(或从源代码生成)并尝试新功能。 这种由经验驱动的反馈对于该过程至关重要。 当进行课程更正的成本较低时,早期采用者会发现错误和可用性问题。 社区可以做的最有价值的事情是:自己尝试代码,并报告您的经验(正面或负面)。

InfoQ:自Java诞生以来,几乎所有的JSR都是严格的编译时间更改,最值得注意的例外是Invoke-Dynamic。 JSR 335是否涉及字节代码级别的任何更改?

Brian:lambda表达式的实现在很大程度上依赖于Java SE 7中引入的invokedynamic。在compiler-writers工具箱中使用invokedynamic使我们避免了很多我们可能会想做的VM工作。 但是,我们添加了两个具有VM影响的功能-默认方法(VM必须参与继承,这最终会影响invokevirtual,invokeinterface和invokespecial特殊字节码的语义),以及接口中的静态方法(主要是放宽了对现有类文件的限制。)

InfoQ:看来IntelliJ Idea已经实现了一些JSR335兼容性。 我想IDE供应商有一些预览版可以使用。 您可以预计何时开始在NetBeans和Eclipse中获得支持吗?

Brian:我们确保所有IDE供应商都在EG上代表,以确保可以通过工具支持这些功能,并且确保IDE供应商可以尽早使用这些规范。 NetBeans拥有基于lambda的构建已有很长时间了。 由于NetBeans使用javac作为其编译器,因此它们具有领先优势。 IntelliJ已经在早期访问版本及其发布的12.x产品中提供了重要的JSR-335支持。 当然,所有这些都在等待规格上的墨水变干。 在那之前,没有什么是最终的。

InfoQ:Lambda的令人兴奋的功能之一是功能语言的外观和感觉,以及用于管道和并发集合的Streams API。 您能谈谈他们是如何设计,实施和协调的吗?

布莱恩:很多事情都是从我们希望用户能够轻松完成的期望用例中倒过来的。 我们查看了其他语言的库以及LambdaJ之类的Java库,特别注意了它们的“展示”示例,并将它们用作“需求”的目录,同时探讨了需要哪种模型来支持它们。 我们还感到至关重要的是,流操作既可以顺序又可以并行工作,并且现有的集合可用作流的源,甚至非线程安全的集合也可以用作并行流的源。 我们计划进行API设计的三个不同的迭代,每个迭代都基于我们从上一个迭代中学到的知识。

InfoQ:Lambdas,闭包,有什么区别的争论。 您的看法是什么?

Brian:我认为弄清Java SE 8中表示的lambda是否是“真正的”闭包是一件很没有建设性的事情。 对我而言,此处使用“真实”一词应该是语法错误; 有许多种具有类似闭包的构造的语言,具有不同程度的相似性和差异性。 声明语言X可以定义真正的闭包是什么,而任何不完全以这种方式做的语言都不是真正的闭包是没有帮助的。

这就是说, 艰难的决定作出关于是否支持到功能,如可变当地采集,非本地控制流,异常透明度和其他功能,而不舍一些手段进行某些使用情况是很难自然地表达的; 这些是表达能力和复杂性之间的折衷,我们尝试将复杂性预算用于对开发人员影响最大的地方。 公平地谈谈每个决策的利弊,但是以“真实与假冒闭包”来形容这并不是建立这种对话的建设性方法。

InfoQ:闭包似乎在接口方面引入了一个悖论:当我们想到接口时,我们想到的是一个可能包含数据和结构但没有实现的结构。 另一方面,闭包实际上是作为数据实现的。 那么Project Lambda是否将允许我们通过定义常量闭合字段在接口中实现功能?

Brian:代码就是数据。 (Godel在大约100年前就向我们讲授了这一点。)Lambda表达式仅使语法表达行为变得容易,这些行为可以轻松地视为数据。

就是说,接口缺乏实现的概念是随Java SE 8一起改变的。为了支持接口演化,我们允许接口提供具有可被类继承的默认主体的方法,并且我们也允许接口中的静态方法。 (使用默认方法的接口可以视为无状态特征的一种形式。)

InfoQ:Lambda引入了“可选”类型。 这如何帮助消除空引用?

Brian:我们对Optional的使用非常有限; 从本质上讲,它只能用作可能不返回任何内容的方法的返回类型。 采取类似Map.get(key)的方法,如果指定的键不在地图中,则该方法返回null。 这有两个严重的缺陷。 第一个是null可能是map元素的有效值(某些地图允许这样做。)现在,您无法分辨出“ not there”和“ mapped to null”之间的区别,以及是否必须进行第二次调用到containsKey()来确定您邀请了竞争条件。 第二个问题是,编写忘记检查是否为null的代码真的很容易,这会使您的代码可靠性降低。 (并且null检查还会使您的代码更丑陋。)当然,保存Map.get()为时已晚,但是我们不必再犯同样的错误。

Optional可以描述一个非null值,也可以显式为空。 您不能盲目地取消引用Optional-bearing方法的返回值,因为类型系统会阻止您。 因此,您必须明确决定如果可选为空,该怎么办; Optional具有get()(如果Optional为空,则抛出异常),getOrElse(defaultValue),getOrThrow(Supplier <E extended Throwable>)等方法,因此,您可以显式但不干扰地编码要在不存在的情况下要执行的操作值-引发异常,替换默认值等

也就是说,那些熟悉Scala中Option的人可能会感到失望; 这不是对类型系统的深刻改变,它只是库中的一个帮助器类,可以更明确地反映“此方法可能不会返回任何内容”,而无需为此目的选择null。

要关注Lambda项目的最新信息,请访问OpenJDK网站上的Lambda项目页面

关于被访者

Brian Goetz是Oracle的Java语言架构师,并且是JSR-335(Java语言的Lambda表达式)的规范负责人。他是畅销书“ Java Concurrency in Practice”的作者,并经常在主要行业会议。

翻译自: https://www.infoq.com/articles/Brian_Goetz_Project_Lambda_from_the_Inside_Interview/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

lambda 匿名内部类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值