闭包在很多语言中都存在,例如C++,C#。闭包允许我们创建函数指针,并把它们作为参数传递,Java编程语言提供了接口的概念,接口中可以定义抽象方法,接口定义了API,并希望用户或者供应商来实现这些方法,很多时候并不是为一些接口创建独立的实现类,我们通过写一个匿名的内部类来写一个内联的接口实现,匿名内部类使用相当的广泛,匿名内部类最常见的场景就是事件处理器了,其次匿名内部类还被用于多线程中,写匿名内部类而不是创建Runable\Callable接口的实现类。
一个匿名内部类就是一个内联的给定接口的实现,这个实现类的对象作为参数传递给一个方法,然后这个方法将在内部调用传递过来的实现类的方法,这种接口叫做回调接口,这个方法叫做回调方法。
匿名内部类很多地方都在使用,在使用的同时存在一些问题
-
复杂
这些类代码的层级看起来很乱很复杂,称作Vertical Problem
-
不能访问封装类的非final成员
this关键字变得很迷惑,如果一个匿名类有一个与其封装类相同的成员名称,内部类会覆盖外部的成员变量,在这种情况下,外部成员在匿名类内部是不可见的,甚至不能通过this来访问。
实例说明
public void test() { String variable = "Outer Method Variable"; new Thread(new Runnable() { String variable = "Runnable Class Member"; public void run() { String variable = "Run Method Variable"; System.out.println("->" + variable); System.out.println("->" + this.variable); } }).start(); } 输出
->Run Method Variable ->Runnable Class Member
这个例子很好的说明了上面的两个问题,而Lambda表达式几乎解决上面的所有问题,我们讨论Lambda表达式之前,让我们来看看Functional Interfaces
-
Funcational Interfaces
一个只有单个方法的接口,这代表了这个方法的契约。
The Single method cal exist in the form of multiple abstract methods that are inherited from superinterfaces.But in that case the inherited methods should logically represent a single method or it might redundantly declare a method that is provided by classes like Object,e.g.toString
> interface Runnable{void run();} > interface Foo {boolean equals(Object obj);} > interface extends Foo{ int compare(String s1,String s2)} > interface Comparetor{ boolean equals(Object obj); int compare(T t1,T t2); } > interface Foo( int m(); Object clone();
大多数回调接口