Reputation: 1599
Suppose we have this class and its inner class:
/* Outer.java */
public class Outer {
private static class Inner {
private final Object foo;
public Inner(Object foo) {
this.foo = foo;
}
public Object getFoo() {
return foo;
}
}
Inner inner = parse(/* someMistery */);
// Question: to access foo, which is recommended?
Object bar = inner.getFoo();
Object baz = inner.foo;
}
I am surprised that inner.foo
works.
Since foo
is private
, it can be accessed only through getFoo()
, right?
Upvotes: 9
Views: 3630
Reputation: 37845
Since
foo
is private, it can be accessed only throughgetFoo()
, right?
In this case, Outer
has access to it too, because Inner
is a member of Outer
.
6.6.1 says:
[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.
Note that it's specified to be accessible within the body of the top level class that encloses the declaration.
This means, for example:
class Outer {
static class Foo {
private Foo() {}
private int i;
}
static class Bar {{
// Bar has access to Foo's
// private members too
new Foo().i = 2;
}}
}
Whether to use a getter or not is really a matter of taste. The important realization here is that outer classes have access to the private members of their nested classes.
As a recommendation, I would personally say:
private
(only the outer class has access to it), I wouldn't bother even giving it a getter unless the getter does a computation. It's arbitrary, and somebody else can come along and choose not to use it. If the styles are mixed, the code has a vagueness. (Do inner.foo
and inner.getFoo()
really do the same thing? We have to go waste time examining the Inner
class to find out.)private
, use the getter so the style is uniform.If you really want to hide the private
members, even from the outer class, you can use a factory with a local or anonymous class:
interface Nested {
Object getFoo();
}
static Nested newNested(Object foo) {
// NestedImpl has method scope,
// so the outer class can't refer to it by name
// e.g. even to cast to it
class NestedImpl implements Nested {
Object foo;
NestedImpl(Object foo) {
this.foo = foo;
}
@Override
public Object getFoo() {
return foo;
}
}
return new NestedImpl(foo);
}
As a pedantic note, your static class Inner {}
is technically a static nested class, not an inner class. class Inner {}
(without static
) would be an inner class.
This is specifically defined to be so:
The
static
keyword may modify the declaration of a member typeC
within the body of a non-inner class or interfaceT
. Its effect is to declare thatC
is not an inner class.
Upvotes: 11
Reputation: 1311
It all depends on your piece of code from where do you want to access that object. Since it is a static nested class, so you will be able to access your object from either ways. Refer to this link http://www.javatpoint.com/static-nested-class for better understanding of inner classes.
Upvotes: 0