6

I have created an inner class in an inner class :

public class EnclosingClass {

    public class InnerClass {
        private EnclosingClass getEnclosing() {
            return EnclosingClass.this;
        }

        public class InnerInnerClass {
            private InnerClass getEnclosing() {
                return InnerClass.this;
            }

            private EnclosingClass getEnclosingOfEnclosing() {
                return EnclosingClass.this;
            }
        }        
    }
}

I have been surprised that java allows the InnerInnerClass to access directly the EnclosingClass. How is this code implemented internally by Java?

The InnerInnerClass keeps two pointers (one on the InnerClass and the other on the EnclosingClass) or the InnerInnerClass access the EnclosingClass through the InnerClass ?

gontard
  • 28,720
  • 11
  • 94
  • 117

4 Answers4

11

You just need to disassemble the resulting class with javap to see what's going on:

private EnclosingClass getEnclosingOfEnclosing();
  Code:
     0: aload_0
     1: getfield      #1                  // Field this$1:LEnclosingClass$InnerClass;
     4: getfield      #3                  // Field EnclosingClass$InnerClass.this$0:LEnclosingClass;
     7: areturn

So first it gets the instance of the directly enclosing class, then it gets the "top-level" enclosing class from that.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

If the inner classes are not 'static', they contain references internally to the class in which they are contained.

Lee Meador
  • 12,829
  • 2
  • 36
  • 42
1

Unless you make an inner class static, then yes, it does have a reference to the instance it exists within, and can reference it members (including private), the same goes for inner inner classes, inner inner inner classes and so on.

Chris Cooper
  • 4,982
  • 1
  • 17
  • 27
0

public and private is a pointer issue, it's a compiler issue.

The question is one of the compiler enforcing the scope of a class/variable/method. Because the private method getEnclosing() falls with the the scope of InnerClass, it can be accessed throughout that class.

Note that pointers have nothing to do with the issue.
Using reflection you can still access private members of a class.

Community
  • 1
  • 1
Johan
  • 74,508
  • 24
  • 191
  • 319