赞
踩
Lambda 表达式是 Java 8 版本的重要新特性。Lambda 表达式可以取代大部分的匿名内部类,可以极大地优化代码结构,让我们的代码更加的优雅。Lambda 表达式的加入,使得 Java 拥有了函数式编程的能力。
Lambda是一个匿名函数,可以理解为一段可以传递的代码。
比如使用Lambda表达式写法启动一个线程,代码如下:
- //使用lambda表达式,启动一个线程
- new Thread(()-> {
- System.out.println("lambda执行了。。。。");
- }).start();
使用面向对象的方式启动一个线程,代码如下:
- //面向对象的方式执行一个线程
- new Thread(new Runnable() {
- @Override
- public void run() {
- System.out.println("线程执行。。。。");
- }
- }).start();
可以发现Lambda表达式的方式要简介许多。
查看Thread的源码。
从中可以分析出几点内容:
Thread
类需要 Runnable
接口作为参数,其中的抽象 run
方法是用来指定线程任务内容的核心 ,为了指定 run
的方法体,不得不需要 Runnable
接口的实现类 ,为了省去定义一个 Runnable
实现类的麻烦,不得不使用匿名内部类 ,且必须覆盖重写抽象 run
方法,所以方法名称、方法参数、方法返回值不得不再写一遍,且不能写错 。而实际上,只有方法体才是关键所在。所以完全可以使用Lambda表达式来完成。
Lambda的语法非常简洁,但是Lambda表达式不是随便使用的,使用时有几个条件要特别注意:
方法的参数或局部变量类型必须为接口才能使用Lambda。比如Thread的参数是Runnable接口。
接口中有且仅有一个抽象方法。比如Runnable接口中只有一个抽象的run方法。
注:
jdk8中可以使用@Functional Interface 注解检测接口是否只有一个方法
Lambda省去面向对象的条条框框,Lambda的标准格式由3个部分组成:
- (参数类型 参数名称) -> {
- 代码体;
- }
格式说明:
(参数类型 参数名称)为参数列表 。
代码体就是要执行的方法体 。
->
箭头,将参数列表和方法体分隔开。
以后调用方法时,看到参数是接口就可以考虑使用Lambda表达式,Lambda表达式相当于是对接口中抽象方法的重写。
在Lambda标准格式的基础上,还可以使用省略的写法进一步简化代码。
其规则为:
小括号内参数的类型可以省略 。
如果小括号内有且仅有一个参数,则小括号可以省略 。没有参数,小括号不能省略。
如果大括号内有且仅有一个语句,可以同时省略大括号、return关键字及语句分号。
- //省略前
- (int a) -> {
- return new Person();
- }
- //省略后
- a -> new Person()
匿名内部类在编译的时候会生成一个class,而Lambda表达式在程序运行的时候会形成一个类 :
在类中新增一个方法,这个方法的方法体就是Lambda表达式中的代码 。
还会形成一个匿名内部类,实现接口,重写接口中的抽象方法 。
在接口的重写方法中会去调用新生成的方法。
把本来我们要重写的代码在运行的时候自动生成并调用。
注
可以结合前面Lambda体验中的Thread类来理解。
所需的类型不一样
匿名内部类,需要的类型可以是类、抽象类、接口 。
Lambda表达式,需要的类型必须是接口 。
抽象方法的数量不一样
匿名内部类所需的接口中抽象方法的数量随意 。
Lambda表达式所需的接口只能有一个抽象方法 。
实现原理不同
匿名内部类是在编译后会形成class 。
Lambda表达式是在程序运行的时候动态生成class。
函数式接口在Java中是指:有且仅有一个抽象方法的接口。
函数式接口,适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以在java中函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能正常的地进行使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。