Re: Confirm bad news



In article <--SdnevlI8ycE9fXnZ2dnUVZ_gSdnZ2d@xxxxxxxxxxxxx>,
"Scott A. Hightower" <VastError@xxxxxxxxxxxxxxx> wrote:

I want to prevent direct access to fields of one nested class from another
nested class within the same enclosing class. It appears that this is not
possible, but before giving up I thought I'd see if someone can point out
something I've overlooked.

It has long bothered me that the private modifer is completely ignored for
intra-class accesses. For example:

class Outer {
class A {...}
class B {private int secret;}
}

A method of inner class A can freely access B.secret, so long as it has a
reference to an instance of B.

The language reference seems to confirm this, stating that (paraphrased) all
members (and members of members, etc.) have scope throughout the compilation
unit. More specifically, from "6.6.1 Determining Accessibility":

"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
... that encloses the declaration of the member or constructor."

Even if class A above is static, it just needs a reference to an instance of
B. I learned this by experiment.

Until now, I've just accepted this, and told myself that there is no need to
encapsulate nested classes because they are usually simple and express
simple concepts. In those rare cases where I wanted to prevent direct
modification, I could make the field a blank final and require creating a
new instance of the nested class, with whatever special logic was required
contained in the sole constructor.

But I've run into a case where I wish to avoid the overhead of creating a
new instance unless absolutely necessary. Sometimes it is safe to directly
modify the value and sometimes a new instance is called for. Therefore, a
blank final cannot be used. But, as soon as the final modifer is removed, I
have opened the door for some future maintainer (even myself) in too much of
a hurry to understand why a new value cannot just be assigned directly.

At this point my choices seem to be comments that warn against direct
modification, or enforcing the encapsulation by moving the nested class into
its own compilation unit. The latter is foolproof, but it seems a shame
because until now the class has been a self-contained standalone utility.

The news is true, in a way. It's definitely not allowed in bytecode.
The source compiler is adding hidden methods to access private fields.

It's assumed that subclasses are friendly to each other. For Java 1.5
onwards, you can break this friendliness by moving the declarations so
they're in the same file but not in a common parent class. This forces
them to be static classes and it stops making accessor methods for them.

class MainClass {
...
}
class A
{
B b;
void foo() {b.secret++;} //Won't compile
}
class B {private int secret;}


I recall that Java 1.4 considers everything in one file to be friendly.

--
I will not see your reply if you use Google.
.



Relevant Pages

  • Re: Need help with calling one class from another
    ... is an object within the other class (InventoryItem). ... The line you say doesn't work isn't accessing the private field, ... I admit, from the code you posted, it's not obvious to me why you have the nested class anyway. ... That said, the issue you're seeing is a basic rule about nested classes: the nested class can see "private" members of the containing class, but not the other way around. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Can nested class members access private members of nesting class?
    ... we are saying about class *Container* with some private members. ... > Nested class Node has all of its members as public so that Container ...
    (comp.lang.cpp)
  • Re: Need help with calling one class from another
    ... isn't accessing the private field, ... value to the nested class anyway. ... the nested class can see "private" members of the containing class, ... private variables. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Nested class: accessing containing classs variables
    ... I'm sure you can just refer to the members by name. ... provide a reference to the enclosing class in order for the nested class to ...
    (microsoft.public.dotnet.languages.vb)
  • Confirm bad news
    ... I want to prevent direct access to fields of one nested class from another ... nested class within the same enclosing class. ... members have scope throughout the compilation ... "Otherwise, if the member or constructor is declared private, then access is ...
    (comp.lang.java.programmer)