I observed that Outer classes can access inner classes private instance variables. How is this possible? Here is a sample code demonstrating the same:
class ABC{
class XYZ{
private int x=10;
}
public static void main(String... args){
ABC.XYZ xx = new ABC().new XYZ();
System.out.println("Hello :: "+xx.x); ///Why is this allowed??
}
}
Why is this behavior allowed?
There's a correct answer appearing on another question similar to this: Why can the private member of an nested class be accessed by the methods of the enclosing class?
It says there's a definition of private scoping on JLS - Determining Accessibility:
The inner class is (for purposes of access control) considered to be part of the containing class. This means full access to all privates.
The way this is implemented is using synthetic package-protected methods: The inner class will be compiled to a separate class in the same package (ABC$XYZ). The JVM does not support this level of isolation directly, so that at the bytecode-level ABC$XYZ will have package-protected methods that the outer class uses to get to the private methods/fields.
An IMHO important use case for inner classes is the factory pattern. The enclosing class may prepare an instance of the inner class w/o access restrictions and pass the instance to the outside world, where private access will be honored.
In contradiction to abyx declaring the class static doesn't change access restrictions to the enclosing class, as shown below. Also the access restrictions between static classes in the same enclosing class are working. I was surprised ...
Inner class is regarded as an attribute of the Outer class. Therefore, no matter the Inner class instance variable is private or not, Outer class can access without any problem just like accessing its other private attributes(variables).
Because your
main()
method is in theABC
class, which can access its own inner class.If you like to hide the private members of your inner class, you may define an Interface with the public members and create an anonymous inner class that implements this interface. Example bellow: