File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Access to Inner Class private members Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Access to Inner Class private members" Watch "Access to Inner Class private members" New topic
Author

Access to Inner Class private members

rajsim
Ranch Hand

Joined: May 31, 2000
Posts: 116
I know that inner classes can access private members of the outer
classes.
It seems that outer classes can also have free access to private
members of inner classes as shown in the following code.
Can anybody point me to a specification confirming this.
Thanks

prints:
Inner->99
Deeper->999
Madhav Lakkapragada
Ranch Hand

Joined: Jun 03, 2000
Posts: 5040

Please observe that you are accessing a private variable
of the class with an obj of that class.
System.out.println ( "Inner->" + new Test().new Inner().i );
In this stmt, you are accessing the private variable 'i'
of the Inner class using an object of that class
right!
Similar reasoning goes to the next println stmt.
Bottomline, Any given obj can access its member variables.
Regds.
- satya

Take a Minute, Donate an Hour, Change a Life
http://www.ashanet.org/workanhour/2006/?r=Javaranch_ML&a=81
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Note - this topic will surely not be on the exam, so y'all can safely ignore this post if the exam is your only interest.]
Well! That's news to me - but yes, I get the same behavior. I can't find a clear statement of what's supposed to happen in the JLS 2nd edition draft - the closest I can come is on p. 122:
<blockquote>A member (class, interface, field, or method) type or a constructor of a class type is accessible only if the type is accessible and the member of constructor is declared to permit access:
[...] if the member or constructor is declared <code>private</code>, then access is permitted if and only if it occurs within the body of the top level class that encloses the declaration of the member.</blockquote>
This seems to confirm the behavior we see - the only problem is that it's not clear that it applies to members within members. Our example has a member field inside a member class. I guess since they offer no other restrictions on the statement, we must take it to apply to all members within the top-level class, no matter how deeply nested. I think.
For what it's worth, I tested this under JDK 1.2.2 and 1.3 running on NT. (I also tried 1.1.8 and got errors, but that's not unusual - 1.1.8 has several bugs when it comes to nested classes.) If anyone has a "modern" compiler that rejects the above code, I'd like to hear about it.


"I'm not back." - Bill Harding, Twister
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Madhav- but you are accessing the private member from outside its class. Consider:
<code><pre>class MyClass {
private member = 99;
}

class Test {
public static void main(String[] s) {
System.out.println(new MyClass().member);
}
}
</pre></code>
This code will not compile, because <code>member</code> is private to <code>MyClass</code>. It doesn't matter that I'm using an instance of <code>MyClass</code> to access it - the problem is that you're trying to access it from outside the definition of <code>MyClass</code>. Can't be done.
I would have expected similar reasoning to apply in rajsim's example as well, but as we see the rule is more subtle than I'd thought.
rajsim
Ranch Hand

Joined: May 31, 2000
Posts: 116
I agree with Jim. In general, you can not access private members from
outside the class.
I have tested the code with jdk1.2.2, jdk1.3 and jikes1.11. All produced
the same results.
rajsim
Ranch Hand

Joined: May 31, 2000
Posts: 116
In addition, please note that the access is not only limited to code in
the enclosing class but also to code within any other inner classes it
might have.
Please see the following code.

Prints:
Inner->99
Deeper->999
Inner2->99
Deeper2->999
Hence, as Jim said, the accessibility is to all the code within the
top-level enclosing class.
In other words, the member of the inner class behave as if they were
members of the top level enclosing class.
If you have any idea about why this kind of access is provided, please
share with us.
Jim Crawford
Ranch Hand

Joined: Sep 08, 2002
Posts: 127


I encountered this 'issue'. Its slightly irretating if its not a bug. Why does there have to be exceptions to the rule if the rule is put there in the first place because of a real and valid reason.
Sigh. This was posted a while ago. Any new ideas on this would be very welcome.
Thanks.


<img src="cool.gif" border="0"> <img src="graemlins/beerchug.gif" border="0" alt="[beerchug]" /> <br />SCJP 1.4
Jim Crawford
Ranch Hand

Joined: Sep 08, 2002
Posts: 127
The insert at the bottom is from Google.
Makes a bit more sense maybe. It seems that inner classes are really not independent, even as far as accessibility is concerned. I thought the access is one way - to the enclosing class private members, but its obviously two way. This must be related to practical implementation detail more than functional requirement. I don't see how this can be the preferred implementation. Encapsulation should hold true even for inner classes... or does it already violate encapsulation rules by what it can do?
:roll:

I don't think "Can't be accessed from outside this class" is
controversial. The issue is what constitutes "this class". If code in a
nested class were considered to be in a different class from the code in
the top level class surrounding it then nested classes would be a lot
less useful.
One could devise an asymetrical approach, in which code in nested
classes is considered to be both inside the nested class and also inside
the top level class, while code in the top level class outside the body
of the nested class is considered to be in a different class from the
nested class, but that would make the rules and their enforcement more
complicated.
It's not clear that the extra complexity would add much to the main
benefit of "private" data, limiting the scope of code that has to be
examined to find all references to it.
Patricia


Link
Jim Crawford
Ranch Hand

Joined: Sep 08, 2002
Posts: 127
I suppose the answer is in the 'private' point below. As mentioned earlier by Jim. This implies that all (non-static) inner classes are treated just as normal class members and all access control is effectively disabled for any enclosed declaration such as nested classes, even if nested to any depth.
This means that nothing declared in a class can be 'invisible' to that class... which would be a no-brainer I suppose if stuff like nested classes didn't exist.
It seems the only reason for declaring inner class members private would then be to make it private to other top-level classes.
Also:
Access control is limited to top-level classes. (?) (since the inner
class permissions are only for use of other top level classes)
Pheew.


6.6.1 Determining Accessibility
* A package is always accessible.
* If a class or interface type is declared public, then it may be accessed by any code, provided that the compilation unit (�7.3) in which it is declared is observable. If a top level class or interface type is not declared public, then it may be accessed only from within the package in which it is declared.
* An array type is accessible if and only if its element type is accessible.
* A member (class, interface, field, or method) of a reference (class, interface, or array) 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:
o If the member or constructor is declared public, then access is permitted. All members of interfaces are implicitly public.
o Otherwise, if the member or constructor is declared protected, then access is permitted only when one of the following is true:
# Access to the member or constructor occurs from within the package containing the class in which the protected member or constructor is declared.
# Access is correct as described in �6.6.2.
o 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.
o Otherwise, we say there is default access, which is permitted only when the access occurs from within the package in which the type is declared.

[ September 03, 2003: Message edited by: Jim Crawford ]
[ September 03, 2003: Message edited by: Jim Crawford ]
Jim Crawford
Ranch Hand

Joined: Sep 08, 2002
Posts: 127
Maybe I just talked a load of non-sense there, but this is quite unfortunate. My design depended on true encapsulation and al last I recogized a nice way to use inner classes. Now all my varibles are out in the open. Why should I have getters and setters now? Why should I go on.. what is the meaning of it all... boohoohoo.....


[ September 03, 2003: Message edited by: Jim Crawford ]
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
Jim,
Inner clasess end up being very useful. Read Why inner classes? by Bruce Eckel.


SCJP2. Please Indent your code using UBB Code
Jim Crawford
Ranch Hand

Joined: Sep 08, 2002
Posts: 127
Thanks!
I found a similar article, but I like Bruce Eckel. His 'Thinking in Java' wasn't bad at all. Hope its mentioned in the JavaRanch resource list.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Access to Inner Class private members