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

Viewed 77

In a .java file, following will not compile:

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

However in jshell, this will work and the output of the first r.run() is 0 and for the second, it is 1. So I want to know how is x accessible to r?

1 Answers

This's how jshell actually works:

class $1 { int x; static void run() { x = 0; } }
class $2 { Runnable r; static void run() { r = () -> print($1.x); } }
class $3 { static void run() { $2.r.run(); } }
class $4 { static void run() { $1.x++; } }
class $5 { static void run() { $2.r.run(); } }

Every time you enter a new command, jshell defines a new class and wraps it as a static method.

You can see the actual class name using new Throwable().printStackTrace()

Related