Lambda 表达式正确执行,但匿名类定义抛出错误

mri*_*aha 3 java functional-interface

我想了解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");
    }
}
Run Code Online (Sandbox Code Playgroud)

您能否告诉我为什么匿名类定义的 lambda 表达式不会导致 StackOverflowError?

And*_*ner 5

你可以在JLS 15.27.2中找到原因(我的重点):

与匿名类声明中出现的代码不同,出现在 lambda body 中的名称和和关键字的含义以及引用声明的可访问性与周围上下文中的相同(除了 lambda 参数引入新名称)。thissuper

也就是说,acceptlambda 体内的名称与acceptlambda 体外的名称具有相同的含义;不同之处在于显式调用匿名类。

因此:accept在定义方法体的 lambda 中调用andThen将涉及实例上的方法(就像直接在方法体中accept调用一样);accept而在匿名类中调用方法accept体将递归地调用自身。accept