lurker
lurker

Reputation: 58244

Scope of private variables within inner classes

Consider the following code:

public class Foo
{
    class Bar
    {
        private String barbar;

        public Bar( String b ) { barbar = b; }
    }

    class Meh
    {
        Bar b = new Bar("BAR!");

        public void displayName() {
            System.out.println( b.barbar );
        }    
    }
}

Java allows class Meh to access the private instance variable, barbar, which is declared as private within Bar.

I know this question has been asked before here. However, the answer just basically reiterates that the observed scope is what it is (that barbar is accessible within the braces of class Foo), but offers no explanation. After some Googling, I hadn't been able to land on a good discussion of this behavior. What I would like to know is if there's a specific rationale for this scoping behavior. I would have expected barbar to be private "within the braces" of class Bar.

Upvotes: 2

Views: 1356

Answers (4)

rajuGT
rajuGT

Reputation: 6404

As per the JLS

The body of a class declares members (fields and methods and nested classes and interfaces), instance and static initializers, and constructors. The scope of a member is the entire body of the declaration of the class to which the member belongs. Field, method, member class, member interface, and constructor declarations may include the access modifiers public, protected, or private.

So, as per the example, class Bar and class Meh both belongs class Foo.

Hence, any member of Foo will have access to all its other members regardless its a field method or nested class/interface as per the first line in the specs.


Comment questioin:

If I made the variable within Bar to be public instead of private would it then become accessible outside of Foo even though it's from an inner class?

Yes of course it is accessible from outside of the class. Look at the below example

class A {

    Foo foo = new Foo();
    Foo.Bar bar = foo.new Bar("name");

    public void someOtherMethod() {
        bar.barbar = "someOtherName"; 
        //this is valid only if barbar is public
        //or if it is default and within the same package
    }

}

Upvotes: 2

Paul
Paul

Reputation: 20061

I don't think you're going to find the rationale behind the design of the language unless you talk to the people who designed it. However, one can often get insight into the "why" through the Java Language Specification. Section 6.3 (Scope of a Declaration) lays out the rules for scoping and has examples of the rules in action.

Specifically, the behavior you're asking about is covered by the statement:

The scope of a local class declaration immediately enclosed by a block is the rest of the immediately enclosing block, including its own class declaration.

Your two local classes have the same scope, i.e. the "immediately enclosing block", specifically class Foo.

Perhaps in your question you can explain why you think barbar should be inaccessible to the enclosing class, and then we can address any misconceptions you have about how Java works.

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074218

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.

Upvotes: 5

lesnar
lesnar

Reputation: 2480

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:

Some piece of functionality in your outer class would be most clear if it was implemented in a separate class. 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.

Upvotes: 1

Related Questions