Home > Enterprise >  How Member Class(Inner class) is accessing instance variable of outer class?
How Member Class(Inner class) is accessing instance variable of outer class?

Time:11-10

I have written below code that is working fine but i have one doubt about synthetic method. As these are generated to access private data. but i am having public instance variable of outer class that is used in member class, so for accessing instance variable it has created synthetic method (As it is in class file!!).

code snippet is as :

public class TestInnerClass {
    public int x = 10;
        public static void main(String[] args) {
            TestInnerClass test= new TestInnerClass();
            A obj = test.new A();
            obj.display();
        }

        class A {
            void display() {
            System.out.println(x);
        }
    }
}

class file is generated as below. For inner class A as TestInnerClass$A:

import java.io.PrintStream;

class TestInnerClass$A {
    TestInnerClass$A(TestInnerClass paramTestInnerClass) {
    }

    void display() {
        System.out.println(this.this$0.x);
    }
}

class file is generated for TestInnerClass :

import java.io.PrintStream;
public class TestInnerClass {
    public int x = 10;
    public static void main(String[] args) { 
        TestInnerClass test = new TestInnerClass();
        TestInnerClass tmp13_12 = test; tmp13_12.getClass(); A obj = new A();
        obj.display();
   } 

   class A {
       A() {
       }
       void display() {
           System.out.println(TestInnerClass.this.x);
       }
   }
}

So my doubt are:

1). why the display method is having different different definition in class files??

2). why in TestInnerClass class file instance variable is accessed as TestInnerClass.this.x. but the same code is different in class file of TestInnerClass$A as this.this$0.x??

3) why JVM created synthetic method as this$0, however instance variable is public??

CodePudding user response:

Not entirely sure I understand your questions but I'll make an attempt to answer them:

  1. why the display method is having different definition in class files?

You can't compare java-files with class-files like that. Some features only exists in one world. Inner classes is one such feature. They don't have a direct translation into bytecode. Some code-massage is necessary, which is what you've discovered here.

  1. why in TestInnerClass class file instance variable is accessed as TestInnerClass.this.x. but the same code is different in class file of TestInnerClass$A as this.this$0.x??

Because when compiling an inner class, the implicit reference to the outer class (TestInnerClass.this) is converted to an explicit reference. Since this reference can't have the identifier this, it is called this$0.

  1. why JVM created synthetic method as this$0, however instance variable is public??

It's not a method, and as far as I can tell, it's not public. It's a field which stores a reference to the object of the enclosing class. It's needed in order to access x of that object.

CodePudding user response:

You can access variables from the outer class because they are in the closure of the inner class. Closures exists in Java but the concept doesn't exists in Java byte code. The synthetic variables and accessors you see are part of the mangling required to make closures work in java byte code.

Full disclosure: Closures in Java aren't actually closures. An actual closure captures the entire environment in which a function is created. In Java an inner class can always access the outer class members and final local variables of the method in which it was created. It can't however access non final local variables as would be possible in a language like say JavaScript.

  • Related