2

Why inner class have access to private field of input object param of such class?

private class Inner {
    private int privatefield = 0;

    public void method( Inner inner ) {
        privatefield = 1; //ok
        inner.privatefield = 1; //this line confusing me (broken incapsulation)
    }
}
pswrdf
  • 95
  • 11
  • If it's private, a class has access to the attribute. Nothing in the package, subclass or overall world has, but everything in the same class does. http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html – Joetjah Aug 29 '13 at 09:15
  • So any private field of inner class is a field of outer class (have no limitation of access). But it's break incapsulation. In my opinion I should have access only to outer fields and inner class fields, but not to fields of another instance of inner class. – pswrdf Aug 29 '13 at 09:39
  • The first situation explained here: [link](http://stackoverflow.com/a/17027518/2728393) – pswrdf Aug 30 '13 at 06:34

7 Answers7

5

This has nothing to do with inner classes per se.

The code within a class always has access to private members of the same class in Java. The notion of private/public etc refers to where the code lives, not whether it refers to "this" instance or a different one. Protected access is a little bit more complicated than other access, but the same general principle applies.

See JLS section 6.6 for more details. In particular:

Otherwise, if the member or constructor is declared private, then 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.

And that explains why one nested class has access to another nested class's private fields, so long as they're nested within the same top-level class, as per your comments. It's an odd rule, I agree - and I prefer C#'s approach in terms of private accessibility and nested types - but the above quote shows that the compiler is obeying the rules of the JLS.

I suspect the reasoning is that if you're working within the same top-level class, you're responsible for all the code within that class, including the nested classes - so you're trusted not to abuse them.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Did you mean that inner class is the same class as outer? – pswrdf Aug 29 '13 at 09:47
  • @pswrdf: No, but all the code you've shown has to do with `Inner`. Your code is in `Inner`, and it refers to an instance of `Inner` - so it has access to the private field. – Jon Skeet Aug 29 '13 at 10:00
  • So if you will use other class of the same level as Inner, you will have access too. Example: `private class Inner { void method(Inner2 inner2) ....} private class Inner2 {}` – pswrdf Aug 30 '13 at 06:03
  • @pswrdf: If you're trying to demonstrate something which is completely different from the question you originally asked, I suggest you ask it in a *different* question. (The answer will still be in section 6.6 of the JLS, I suspect - although not the motivation.) – Jon Skeet Aug 30 '13 at 06:05
  • @pswrdf: I've edited my answer to show exactly which bit allows that. – Jon Skeet Aug 30 '13 at 06:07
  • This rule speak about only top level class. And thats right because outer class own it's nest classes. But one nested class have access to another nested if they are the same - outer. Then the rule work. The around answer is here: [link](http://stackoverflow.com/a/17027518/2728393) – pswrdf Aug 30 '13 at 06:27
  • @pswrdf: No, the rule speaks about *every* private member - but the accessibility domain is based on the top-level class. See my bottom paragraph for my suspected justification. – Jon Skeet Aug 30 '13 at 07:08
0

Why inner class have access to private field of input object param of such class?

  • Even though private, inner class is a member of outer class
  • private members are accessible for the class members.
Prasad Kharkar
  • 13,410
  • 5
  • 37
  • 56
0

Consider that your class isn't nested neither private, cause it's irrelevant with your question. It has to do with scope visibility.

Declaration says

private modifier — the field is accessible only within its own class.

Since you access the privatefield property inside the class that is declared even if it's a member of a different instance your encapsulation isn't broken,private scope is maintained.

giannis christofakis
  • 8,201
  • 4
  • 54
  • 65
0

Any method within a class can access a global variable inside that class. The private parameter only makes it so that OTHER classes can not access the variable.

In this case the methods in Inner will be able to find the var and methods outside of Inner will not be able to.

DrkNess
  • 676
  • 5
  • 4
0

If you see Docs of Controlling Access to Members of a Class

The private modifier specifies that the member can only be accessed in its own class.

Since privatefield is member of your class, you have access inside the class.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
0

Since the method(Inner inner) resides in the Inner class, hence method(Inner inner) can access the member private to the Inner class.

Gaurav Gupta
  • 4,586
  • 4
  • 39
  • 72
0

Access modifiers define the scope in which your variable can be accesses and not whether individual instances can access it or not!

private int privatefield = 0;

Your variable is non static so it will be accesses by instance of the class. So inner.privatefield makes sense. Now your variable privatefield is private which means you can access it inside your Inner class. Since your are accessing the variable inside method() which is inside Inner class there is no problem and is perfectly valid.

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289