I'm trying to learn what visibility to assign to nested classes, besides what my IDE yells at me that I have to do. This can get arbitrarily complicated, so I need to understand the general rules.
public class A {
private static class B {
public int foo; // accessible in A?
private int bar; // accessible in A?
public static class C { // accessible in A? everywhere?
}
private static class D { // accessible in A?
}
}
}
As far as I understand, modifiers seem to resolve at the "file" level, not at the level of the encapsulating class. Once one thing is private, anything inside it is private.
What's the actual mechanism of this or the technical explanation? Is this documented somewhere or do I just need to read the JLS?
As a member of the OuterClass , a nested class can be declared private , public , protected , or package private. (Recall that outer classes can only be declared public or package private.)
Nested inner classes have access to the members of the outer class, including the private ones. A nested class can be public, private, package private, or protected as a member of the outer class. The outer java classes can access inner class private or protected members.
We can use all of the standard visibility modifiers on inner classes, so a static inner class could be private, protected, default, or publicly visible.
Java inner class can be declared private, public, protected, or with default access whereas an outer class can have only public or default access.
One of the best summaries of access visibility that I've seen is in the Java Tutorials > Controlling access to members of a class, but it glosses over some of the key details. The question I think you are asking is answered in § 6.6.1 of the JLS for SE 7: "Determining Accessibility"
If ... public ... Otherwise, if ... protected ... Otherwise, if ... package 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.
If you read that carefully:
private
(not package-private - that's different) memberSo: any member inside any depth of private nested classes is accessible anywhere within the body of the top level class (including within other nested sibling classes). However a private nested class, and any member within, is not visible to other top level classes.
For example:
public class A {
private static class B {
public int foo; // accessible in A and P
private int bar; // accessible in A and P
public static void test(){
P p = new P();
p.foo = 1; p.bar = 1;
}
}
private static class P {
public int foo; // accessible in A and B
private int bar; // accessible in A and B
public static void test(){
B b = new B();
b.foo = 1; b.bar = 1;
}
}
public static void test(){
B b = new B();
b.foo = 1; b.bar = 1;
P p = new P();
p.foo = 1; p.bar = 1;
}
}
Note: This isn't "file level" though. Declare another top level class in that file (which could not be public
- only one of those allowed per file) and it couldn't see those same nested private
members.
class X {
public static void test() {
// all of these statements fail ...
A.B b = new A.B();
b.foo = 1; b.bar = 1;
b.test();
A.P p = new A.P();
p.foo = 1; p.bar = 1;
p.test();
}
}
Accessibility is relative to the access source. First
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 all members you've declared in A
or nested within class in A
are accessible in A
.
If you're not within A
, then private
members of A
are not accessible. That means B
is not accessible. Since foo
, bar
, C
and D
are members of B
, you need B
to access them. But since B
is not accessible, you can't access those either.
public class Unrelated {
{
B b; // nope
A.B b; // nope
A.B.C c; // nope
}
}
These rules are more or less all defined in this section of the JLS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With