I have the following java class:
class Outer
{
private Integer a;
private Long b;
class Inner
{
public void foo()
{
System.out.println("a and b are " + a + " " + b);
}
}
}
when I run javap on Outer and Outer$Inner, I get the following:
C:\test>javap Outer
Compiled from "Outer.java"
class Outer extends java.lang.Object{
Outer();
static java.lang.Integer access$000(Outer);
static java.lang.Long access$100(Outer);
}
C:\test>javap Outer$Inner
Compiled from "Outer.java"
class Outer$Inner extends java.lang.Object{
final Outer this$0;
Outer$Inner(Outer);
public void foo();
}
I have two questions:
1) why does java compiler generate static methods that take 'Outer' param, in the outer class, for accessing its private variables ? why not instance methods that the inner class can easily call through its this$0 member ?
2) why is this$0 in inner class made final ? what will happen if it is not final ?
Thanks and regards.
Non-static inner classes have an implicit reference to an instance of the outer class. This is implemented as a final
reference to the outer class. If it wasn't final
technically it could be modified after instantiation.
The outer class is implicitly passed in which is why any constructors on the inner class have an implicit parameter of the outer class, which is how this$0
is passed in.
Edit: as for the access$000
methods the key clue is that they're package access and they take an Outer
as an argument. So when code in Inner
calls, say, Inner.this.a
it's actually calling Inner.access$000(this$0)
. So those methods are there to give access to private
members of the outer class to the inner class.