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

Why jshell allows non-final free variables in lambda expressions?

.java 文件中,以下将无法编译:

class Test {
    public static void main(String[] args) {
        int x = 0;
        Runnable r = () -> System.out.println(x);
        r.run();
        x++;
        r.run();
    }
}

但是在 jshell 中,这会起作用,第一个 r.run() 的输出是 0,第二个是 1。所以我想知道 x 如何访问 r

这就是 jshell 的实际工作方式:

class  { int x; static void run() { x = 0; } }
class  { Runnable r; static void run() { r = () -> print(.x); } }
class  { static void run() { .r.run(); } }
class  { static void run() { .x++; } }
class  { static void run() { .r.run(); } }

每次输入一个新的命令,jshell都会定义一个新的class并将其包装成一个静态方法

您可以使用 new Throwable().printStackTrace()

查看实际的 class 名称