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
?
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()