How does optimization of final references work in java?
compilation, java, optimization
Solution
Does `jd-gui` decompiles incorrectly or do I missing something about Java compilation and optimization?
`jd-gui` is decompiling the code incorrectly.
On my JVM, the disassembled code for the anonymous class looks as follows:
class Clazz$1 extends Clazz {
Clazz$1(java.lang.Integer);
Code:
0: aload_0
1: aload_1
2: putfield #10 // Field val$i:Ljava/lang/Integer;
5: aload_0
6: invokespecial #12 // Method Clazz."<init>":()V
9: return
void foo();
Code:
0: getstatic #20 // Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_0
4: getfield #10 // Field val$i:Ljava/lang/Integer;
7: invokevirtual #26 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
10: return
}
As you can see, a copy of `i` stored in the anonymous class, in the field called `val$i` (the name is implementation-specific).
It is this field that your decompiler appears to incorrectly render as `Clazz.this`.
Problem
I'd been trying to figure out all about Java optimizations and found something interesting. First case: primitive type compile-time optimization ``` public class Clazz { public static void main(String args[]) { final int i = 300; new Clazz() { void foo() { System.out.println(i); } }.foo(); } } ``` After compilation (I'm using `jd-gui-0.3.5.windows` to decompile binary files) it is looks like: ``` public class Clazz { public static void main(String[] args) { int i = 300; new Clazz() { void foo() { System.out.println(300); } }.foo(); } } ``` As expected, isn't it? `i` was replaced with it's value (inlining optimization) after compilation. So, I expected to see something similar after replacing primitive type with it's wrapper, but... Second case: non-primitive type compile-time optimization ``` public class Clazz { public static void main(String args[]) { final Integer i = 300; // replaced int with Integer new Clazz() { void foo() { System.out.println(i); } }.foo(); } } ``` After compilation: ``` public class Clazz { public static void main(String[] args) { Integer i = Integer.valueOf(300); new Clazz() { void foo() { System.out.println(Clazz.this); } }.foo(); } } ``` Questions: What is `Clazz.this` in this context? I know, that it is reference to enclosing instance of `Clazz`, but it should not work in that case! I need to print `i`, but compiler suggests me to print `Clazz.this` instead of it and it works! What is the problem? Does `jd-gui` decompiles incorrectly or do I missing something about Java compilation and optimization? UPD: Content of `Class$1`: ``` class Clazz$1 extends Clazz { Clazz$1(Integer paramInteger) {} void foo() { System.out.println(this.val$i); } } ```