Calls to inner class super constructor and putfield
Gordon Syme
gordon at twiceasgood.net
Wed Sep 23 03:38:48 PDT 2009
Hi all,
I have noticed that when an inner class is compiled the call to store
the outer class instance reference in the synthetic 'this$n' field
occurs before the call to the inner class's super constructor.
I was under the impression that you needed a fully initialised reference
as the dispatching operand for a putfield. Is it valid to use putfield
with an unitialised reference? The VM Spec doesn't explicitly mention
this either way, just that the operand must be an objectref.
E.g. for the following Java code:
public class Test {
public class Inner {
public int i;
public Inner(int i) {
this.i = i;
}
}
public static void main(String[] args) {
Test t = new Test();
Test.Inner inner = t.new Inner(1);
}
}
The bytecodes generated for Inner's constructor by javac 1.6.0_16 are:
0 aload_0
1 aload_1
2 putfield #1 <Test$Inner.this$0>
5 aload_0
6 invokespecial #2 <java/lang/Object.<init>>
9 aload_0
10 iload_2
11 putfield #3 <Test$Inner.i>
14 return
However, when the same code is compiled targeting a VM less than 1.4
(e.g. 1.3) the invokespecial occurs /before/ the putfield to this$0.
0 aload_0
1 invokespecial #1 <java/lang/Object.<init>>
4 aload_0
5 aload_1
6 putfield #2 <Test$Inner.this$0>
9 aload_0
10 iload_2
11 putfield #3 <Test$Inner.i>
14 return
It is clearly an intentional change but I can't for the life of me
figure out why (and Google hasn't been much help). I'd very much
appreciate a pointer or two if anybody has the time.
Thanks
-Gordon
More information about the compiler-dev
mailing list