Why do inner classes make private methods available?

I do not understand why this compiles. f () and g () are visible from inner classes, despite the fact that they are private. Are they considered specifically because they are inner classes?

If A and B are not static classes, that's the same.

class NotPrivate { private static class A { private void f() { new B().g(); } } private static class B { private void g() { new A().f(); } } } 
+24
java inner-classes
Mar 19 '09 at 17:01
source share
3 answers

(Editing: added in response to answer some comments)

The compiler takes inner classes and turns them into top-level classes. Since private methods are only available to the inner class, the compiler must add new โ€œsyntheticโ€ methods that have access to the package level so that top-level classes have access to it.

Something like this (added by the $ compiler):

 class A { private void f() { final B b; b = new B(); // call changed by the compiler b.$g(); } // method generated by the compiler - visible by classes in the same package void $f() { f(); } } class B { private void g() { final A a; a = new A(); // call changed by the compiler a.$f(); } // method generated by the compiler - visible by classes in the same package void $g() { g(); } } 

Non-static classes are the same, but they have the addition of a reference to an external class so that methods can be called on it.

The reason Java does this is because they do not want to require changes to the VM to support the inner classes, so all the changes had to be at the compiler level.

The compiler takes the inner class and turns it into a top-level class (thus, at the VM level there is no such thing as an inner class). Then the compiler should generate new methods of "transfer". They are created at the package level (not publicly available) to provide access to them only for classes in one package. The compiler has also updated method calls for private methods for generated forwarding methods.

You can prevent the compiler from generating a method that declares methods as a โ€œpackageโ€ (lack of public, private, and protected). The disadvantage of this is that any package class can call methods.

+26
Mar 19 '09 at 17:24
source share

I think this quote sums up:

... inner classes can access all members of the declaring class, even private members. In fact, the inner class itself is considered a member of the class; therefore, following the rules of object-oriented design, it must have access to all members of the class.

And following this, since both inner classes are really only part of the containing class, they should also have access to other private members.

+13
Mar 19 '09 at 17:09
source share

Java compiles in special accessors with $ in them. Thus, you cannot write Java, access to private methods. Explained here:

http://www.retrologic.com/innerclasses.doc7.html

There is another category of members created by the compiler. The private member m of class C can be used by another class D if one class encloses another, or if it is enclosed in a common class. Since the virtual machine does not know about this grouping, the compiler creates a local protocol of access methods in C to allow D to read, write, or call the m element. These methods have access form names $ 0, access $ 1, etc. They are never publicly available. Access methods are unique in that they can be added to closing classes, and not just to inner classes.

+3
Mar 19 '09 at 17:06
source share



All Articles