从前面的整理中我们看出了,Lambda表达式其实是匿名内部类的一种简化,因此它可以部分取代匿名内部类。
- 1,Lambda表达式与匿名内部类存在如下相同点:
1),Lambda表达式与匿名内部类一样,都可以直接访问“effectively final”的局部变量,以及外部类的成员变量
2),Lambda表达式创建的对象与匿名内部类生成的对象一样,都可以直接调用从接口中继承的默认方法。
我们还是写一段代码来看一下吧:
/**
* @创建作者: LinkinPark
* @创建时间: 2015年10月27日
* @功能描述: Lambda表达式和匿名内部类对比
*/
public class Test
{
private int age = 25;
private static String name = "LinkinPark..."; public void test()
{
String finalName = "NightWish";
//实现函数式接口,创建一个对象
A a = () ->
{
//1,访问“effectively final”变量
System.out.println("访问局部变量:" + finalName);
//Local variable finalName defined in an enclosing scope must be final or effectively final代码报错
//finalName = "NightWish...";
//2,访问外部类的实例变量
System.out.println("访问外部类的实例变量:" + age);
//3,访问外部类的类变量
System.out.println("访问外部类的类变量:" + name);
//4,Lambda表达式的代码块中不允许调用接口中定义的默认方法,下面代码报错
System.out.println(getAge());
};
a.test();
//调用A接口的静态方法和默认方法
System.out.println(A.getName());
System.out.println(a.getAge());
} public static void main(String[] args)
{
new Test().test();
} } @FunctionalInterface
interface A
{
void test(); static String getName()
{
return "函数式接口的静态方法。。。";
} default String getAge()
{
return "函数式接口的默认方法。。。";
}
}
上面的代码阅读没什么问题,有一点要注意的是,由于Lambda表达式访问了finalName的局部变量,因此该局部变量相当于有一个final修饰,所以不能重新赋值。
- 2,Lambda表达式与匿名内部类的区别
1),匿名内部类可以为任意的接口创建实例,不管接口包含多少个抽象方法,只要匿名内部类实现所有的抽象方法就好,但是Lambda表达式只能为函数式接口创建实例。
2),匿名内部类可以为抽象类后者普通类创建实例,但是lambda表达式只能为函数式接口创建实例。
3),匿名内部类实现的抽象方法的方法体允许调用接口中定义的默认方法,但是Lambda表达式的代码块不允许调用接口中定义的默认方法。