You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Java中Lambda正常执行但匿名类实现会抛出StackOverflowError?

问题

我正在理解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?

原因分析

核心差异在于方法调用的上下文指向不同:

  • Lambda版本中,accept(t)调用的是调用andThen方法的外部Interface实例(也就是e1)的accept方法。Lambda在andThen方法的上下文中创建,默认捕获了外部实例的引用,执行时会先运行e1的逻辑,再运行after(也就是e2)的逻辑,不会出现递归。
  • 匿名类版本中,重写的accept方法里的accept(t)没有指定调用对象,默认是调用当前匿名类对象自己的accept方法,这就导致了无限递归调用:每次调用这个匿名类的accept,都会再次调用自己,不断压入栈帧,最终触发StackOverflowError。

如果要修复匿名类的问题,需要明确指定调用外部实例的accept方法,修改为:

Interface.this.accept(t);

这样就能和Lambda版本的逻辑一致,先执行外部实例(e1)的accept,再执行after(e2)的accept。

内容的提问来源于stack exchange,提问作者mrinmoy saha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:52:46