Can Inner Classes Access Private Variables

Scope of private variables within inner classes

The fundamental aspect of this is that inner classes (as opposed to static nested classes) are part of their enclosing class. They aren't separate from it, or from each other. So just like other parts of the enclosing class (constructors and methods) have access to all of its private information, so do all the members of the inner classes. Inner classes are, in some sense, a bit of a fiction that we use as a convenient abstraction mechanism. And since inner classes are part of the enclosing class, their private information is its private information, and so is shared with other inner classes.

C++ Outer class access Inner class's private - why forbidden

Essentially, within a scope names declared earlier in that scope are valid and can be used directly (unless they're shadowed). Code outside a scope can't directly use names declared inside the scope. E.g. code after a curly braces block, can't directly use variables declared inside that block (an example of indirect use is when the outside code has access to a pointer to a static variable inside the curly braces block).


For the second example, just make Algorithm a friend of AlgorithmResults:

class AlgorithmResults
{
friend class Algorithm;

Inner classes can access even the private members of the outer class.. doesn't it violates the privacy?

From a JVM perspective, yes, an inner class accessing a private member of the outer class violates privacy.

But, from a Java perspective, no, it does not violate privacy.

JVM perspective

The Java Virtual Machine Specification, section 5.4.4. Access Control says:

A field or method R is accessible to a class or interface D if and only if any of the following is true:

  • [...]

  • R is private and is declared in D.

So, the JVM will only allow private members to be accessed from code in the same class, i.e. a nested class cannot access private members of the outer class.

Java perspective

The Java Language Specification, section 6.6.1. Determining Accessibility says:

A member (class, interface, field, or method) of a reference type, or a constructor of a class type, is accessible only if the type is accessible and the member or constructor is declared to permit access:

  • [...]

  • Otherwise, the member or constructor is declared private, and access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

So, a private member in a top-level class and/or nested class is accessible from code anywhere within that top-level class. Since nested classes by definition occur within the body of the enclosing top-level class, code in nested classes can access private members of the outer class.

Synthetic access

To solve the discrepancy, the Java compiler creates hidden (synthetic) methods for allowing "private" access between closely related classes, i.e. between a top-level class and all its nested classes.

This is an internal trick of the compiler and is not really documented in the specifications. JVMS, section 4.7.8. The Synthetic Attribute says:

[...] A class member that does not appear in the source code must be marked using a Synthetic attribute, or else it must have its ACC_SYNTHETIC flag set. [...]

The Synthetic attribute was introduced in JDK 1.1 to support nested classes and interfaces.

For more information, do a web search for java synthetic accessor.

See also: Synthetic accessor method warning

Why can outer Java classes access inner class private members?

The inner class is just a way to cleanly separate some functionality that really belongs to the original outer class. They are intended to be used when you have 2 requirements:

  1. Some piece of functionality in your outer class would be most clear if it was implemented in a separate class.
  2. Even though it's in a separate class, the functionality is very closely tied to way that the outer class works.

Given these requirements, inner classes have full access to their outer class. Since they're basically a member of the outer class, it makes sense that they have access to methods and attributes of the outer class -- including privates.

Static nested class has full access to private outer class members?

The answer to which you link is not entirely correct: nested static classes have access to all members of its enclosing class, including private members.

They do not get access to instance members, public or private, of its enclosing instance. However, if you pass a method of a static nested class an instance of the enclosing class, the nested class would be able to access all members of the enclosing class, regardless of their access level.

I think the static/non-static confusion comes from this line of JLS:

Member classes may be static, in which case they have no access to the instance variables of the surrounding class

This does not mean that static nested classes have no access to instance variables at all. It means that static nested classes have no access to instance variables of the enclosing class "for free", the way the non-static nested classes do.

To me, the two main differences between a static nested class and a top-level class are

  1. Nested static classes and interfaces express a closer association with their enclosing classes / interfaces. For example, Map.Entry nested interface is a better choice than MapEntry top-level interface for readability.
  2. Nested classes can serve as an implementation detail of another class, if you declare them private. You cannot do that with top-level classes, because they would remain accessible at least to the classes in the same package.

Can an outer class access the members of inner class?

If the inner class defined as private
and protected, can outer class access
the members of inner class?

Yes. These qualifiers will only affect the visibility of the inner class in classes that derive from the outer class.

Can inner class access members of
outer class?

Yes, including the ones declared private, just as any instance method can.



Related Topics



Leave a reply



Submit