Lambda表达式
外部变量访问
与匿名内部类类似,Lambda表达式也可以访问定义在主体代码外部的变量,但对于局部变量,它也只能访问final类型的变量,与匿名内部类的区别是,它不要求变量声明为final,但变量事实上不能被重新赋值。比如
String msg = "hello world"; executor.submit(()->System.out.println(msg));
可以访问局部变量msg,但msg不能被重新赋值,如果这样写就会报错:
String msg = "hello world"; msg = "good morning"; executor.submit(()->System.out.println(msg));
原因:匿名内部类是一样的,Java会将msg的值作为参数传递给Lambda表达式,为Lambda表达式建立一个副本,它的代码访问的是这个副本,而不是外部声明的msg变量。如果允许msg被修改,则程序员可能会误以为Lambda表达式读到修改后的值,引起更多的混淆。
底层实现
利用invokedynamic指令、方法句柄(method handle)等实现,具体参考:http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html
函数式接口
函数式接口是什么?java预定义了哪些函数式接口?
函数式接口也是接口,但只能有一个抽象方法:
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
@FunctionalInterface用于清晰地告知使用者这是一个函数式接口,不过,这个注解不是必需的,不加,只要只有一个抽象方法,也是函数式接口。但如果加了,而又定义了超过一个抽象方法,Java编译器会报错,这类似于我们之前介绍的Override注解。
Java预定义的函数式接口:
知其然知其所以然,只有掌握了底层原理,借助第一性原理,才可以在日常开发和项目中运用自如,潇洒走江湖。 专为27届毕业生准备,托起您的就业梦。 该专辑会不定时更新,建议27届同学订阅,入职后扎实的基本功可以帮您争取更好的机会和项目。
