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); } } ```

Original source