我正在尝试了解Java的Consumer接口。我已经复制了。但是当我用匿名类定义替换 andThen() 方法的返回语句中的 lambda 表达式时,它会抛出 StackOverflowError :
interface Interface<T> {
void accept(T t);
default Interface<T> andThen(Interface<T> after) {
//return (T t)->{accept(t); after.accept(t);};//this runs correctly
//below is the anonymous class definition of above lambda expression
return new Interface<T>(){
@Override
public void accept(T t)
{
accept(t); //stackoverflow error thrown
after.accept(t);
}
};
}
}
//Main class:
public class Lambda2 {
public static void main(String args[]) {
Interface<String> e1=str -> System.out.println("in e1 - "+str);
Interface<String> e2=str -> System.out.println("in e2 - "+str);
Interface<String> e3 = e1.andThen(e2);
e3.accept("Sample Output");
}
}
请问为什么匿名类定义的lambda表达式不会导致StackOverflowError?
你可以在JLS 15.27.2找到原因(我的重点):
与匿名类声明中出现的代码不同,名称的含义以及 this 和 super 关键字出现在 lambda 体中,以及引用声明的可访问性,与周围上下文中的相同(除了lambda 参数引入了新名称)。
也就是说,lambda 体内的名称
apply
与 lambda 体外的 apply
具有相同的含义;不同之处在于显式调用了匿名类。