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

为什么jshell允许lambda表达式中使用非final的自由变量?

问题代码复现
class Test {
    public static void main(String[] args) {
        int x = 0;
        Runnable r = () -> System.out.println(x);
        r.run();
        x++;
        r.run();
    }
}
常规.java文件编译报错原因

Java 语言规范明确要求:lambda 表达式如果捕获方法内的局部变量,该变量必须是final修饰,或者是有效final(变量赋值后从未被修改)。上述代码中x后续执行了x++修改操作,不满足有效final的要求,因此标准Java编译器会直接抛出编译错误,代码无法正常构建。

JShell中代码正常执行的原因及x的访问逻辑

JShell是Java 9+推出的交互式REPL工具,它的执行环境和常规.java文件的编译执行逻辑有本质区别:

  • 你在JShell交互环境中直接定义的顶层变量,本质是JShell内部执行上下文的堆分配成员变量,不是普通方法内栈分配的局部变量,天然不受lambda捕获局部变量的有效final规则限制。
  • JShell处理lambda对可变变量的捕获时,不会像常规编译一样拷贝变量的当前值,而是让lambda持有变量的引用。因此第一次调用r.run()时访问的是初始值0,执行x++修改了同一份引用指向的存储值,第二次调用r.run()自然就能拿到修改后的1。

内容的提问来源于stack exchange,提问作者Mahek Shamsukha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:00:00