You can notice what happens underneath by simply decompiling the inner class. Here is a short example:
After compiling this piece of code:
public class Test {
public void method() {
final Object handle = new Object();
Thread thread = new Thread() {
public void run() {
handle.toString();
}
};
thread.start();
}
}
you will get Test.class
for Test.java
and Test$1.class
for the inner class in Test.java
. After decompiling the Test$1.class
you will see this:
class Test$1 extends Thread
{
final Test this$0;
private final Object val$handle;
public void run()
{
this.val$handle.toString();
}
}
As you can see instead of handle
variable there is this.val$handle
. This means that handle
is copied as a val$handle
field to the inner class. And this will work correctly only if the handle
will never change - which in Java means it must be final
.
You can also notice that the inner class has a field this$0
which is a reference to the outer class. This in turn shows how non static inner classes are able to communicate with outer classes.