微信号:infoqchina

介绍:有内容的技术社区媒体

Java SE 8: Lambda表达式

2013-08-22 15:39 InfoQ

Java SE 8在6月13的版本中已经完全了全部的功能。在这些新的功能中,lambda表达式是推动该版本发布的最重要新特性。因为Java第一次尝试引入函数式编程的相关内容。社区对于lambda表达式也期待已久。Lambda表达式的相关内容在JSR 335中定义,本文的内容基于最新的规范和JDK 8 Build b94。 开发环境使用的是Eclipse。


Lambda表达式


要理解lambda表达式,首先要了解的是函数式接口(functional interface)。简单来说,函数式接口是只包含一个抽象方法的接口。比如Java标准库中的java.lang.Runnable和java.util.Comparator都是典型的函数式接口。对于函数式接口,除了可以使用Java中标准的方法来创建实现对象之外,还可以使用lambda表达式来创建实现对象。这可以在很大程度上简化代码的实现。在使用lambda表达式时,只需要提供形式参数和方法体。由于函数式接口只有一个抽象方法,所以通过lambda表达式声明的方法体就肯定是这个唯一的抽象方法的实现,而且形式参数的类型可以根据方法的类型声明进行自动推断。


以Runnable接口为例来进行说明,传统的创建一个线程并运行的方式如下所示:



在上面的代码中,首先需要创建一个匿名内部类实现Runnable接口,还需要实现接口中的run方法。如果使用lambda表达式来完成同样的功能,得到的代码非常简洁,如下面所示:



相对于传统的方式,lambda表达式在两个方面进行了简化:首先是Runnable接口的声明,这可以通过对上下文环境进行推断来得出;其次是对run方法的实现,因为函数式接口中只包含一个需要实现的方法。


Lambda表达式的声明方式比较简单,由形式参数和方法体两部分组成,中间通过“->”分隔。形式参数不需要包含类型声明,可以进行自动推断。当然在某些情况下,形式参数的类型声明是不可少的。方法体则可以是简单的表达式或代码块。


Lambda表达式“(x, y) -> y - x“实现了java.util.Comparator接口。


在Java SE 8之前的标准库中包含的函数式接口并不多。Java SE 8增加了java.util.function包,里面都是可以在开发中使用的函数式接口。开发人员也可以创建新的函数式接口。最好在接口上使用注解@FunctionalInterface进行声明,以免团队的其他人员错误地往接口中添加新的方法。


方法和构造方法引用


方法引用可以在不调用某个方法的情况下引用一个方法。构造方法引用可以在不创建对象的情况下引用一个构造方法。方法引用是另外一种实现函数式接口的方法。在某些情况下,方法引用可以进一步简化代码。比如下面的代码中,第一个forEach方法调用使用的是lambda表达式,第二个使用的是方法引用。两者作用相同,不过使用方法引用的做法更加简洁。

接口的默认方法


Java开发中所推荐的实践是面向接口而不是实现来编程。接口作为不同组件之间的契约,使得接口的实现可以不断地演化。不过接口本身的演化则比较困难。当接口发生变化时,该接口的所有实现类都需要做出相应的修改。如果在新版本中对接口进行了修改,会导致早期版本的代码无法运行。Java对于接口更新的限制过于严格。在代码演化的过程中,一般所遵循的原则是不删除或修改已有的功能,而是添加新的功能作为替代。已有代码可以继续使用原有的功能,而新的代码则可以使用新的功能。但是这种更新方式对于接口是不适用的,因为往一个接口中添加新的方法也会导致已有代码无法运行。


接口的默认方法的主要目标之一是解决接口的演化问题。当往一个接口中添加新的方法时,可以提供该方法的默认实现。对于已有的接口使用者来说,代码可以继续运行。新的代码则可以使用该方法,也可以覆写默认的实现。


更多请阅读全文。


***********************************

本文来自InfoQ微信公众账号:infoqchina

1、回复“今日新闻”,查看今天更新的新闻;

2、回复“今日英文”,查看今天英文站的更新;

3、回复“文章 +关键词”,搜索关键词相关内容;

4、回复“QCon”,了解QCon大会相关信息;

5、回复“活动”,了解最近InfoQ组织的线下沙龙;

6、回复“架构师”,获取《架构师》下载地址;

7、回复“投稿”,了解投稿和加入编辑团队的流程。

***********************************

 
InfoQ 更多文章 Facebook如何实现PB级别数据库自动化备份 学术派Google软件工程师Matt Welsh谈移动开发趋势 Spotify为什么要使用一些“无聊”的技术? 妹纸们放假了,汉纸们做啥? 大多数重构可以避免
猜您喜欢 Swift高阶函数:Map,Filter,Reduce等-Part 1 perl 模块推荐10_Tie-File 阿里聚安全一周一讯 | 为防iPhone间谍软件,苹果发布iOS 9.3.5、微信曝远程任意代码执行漏洞,可被远程控制 【HKOSCon 2016】How to Build a NewSQL Database? 细说Oracle数据库与操作系统存储管理二三事