Da foo
privat ist, kann es nur über getFoo()
zugegriffen werden, richtig?
In diesem Fall hat Outer
Zugang zu ihm zu, weil Inner
Mitglied Outer
ist.
6.6.1 sagt:
[Wenn] das Mitglied oder Konstruktor private
deklariert wird, [dann] Zugriff erlaubt ist, wenn und nur wenn es innerhalb des Körpers der Top-Level-Klasse tritt, der die Erklärung umschließt des Mitglieds oder Konstruktors.
Beachten Sie, dass es angegeben ist innerhalb des Körpers der Top-Level- Klasse zugänglich zu sein, der die Erklärung einschließt.
Das bedeutet zum Beispiel:
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;
}}
}
Ob ein Getter verwenden oder nicht wirklich eine Frage des Geschmacks ist. Die wichtige Erkenntnis hierbei ist, dass äußere Klassen Zugriff auf die privaten Mitglieder ihrer verschachtelten Klassen haben.
Als Empfehlung, würde ich persönlich sagen:
- Wenn die verschachtelte Klasse
private
ist (nur die äußere Klasse Zugriff darauf hat), würde ich nicht einmal die Mühe, es einen Getter zu geben, es sei denn der Getter tut eine Berechnung. Es ist willkürlich, und jemand anderes kann mitkommen und beschließen, es nicht zu benutzen. Wenn die Stile gemischt sind, hat der Code eine Ungenauigkeit. (Do inner.foo
und inner.getFoo()
wirklich das gleiche tun? Wir müssen Zeit gehen Prüfung der Inner
Klasse, um herauszufinden.)
- Aber Sie könnten durch einen Getter sowieso gehen, wenn das der Stil ist, mit denen Sie sich wohl fühlen.
- Wenn die verschachtelte Klasse nicht
private
ist, verwenden Sie den Getter, so dass der Stil einheitlich ist.
Wenn Sie wirklich wollen die private
sich dahinter zu verstecken, auch von der äußeren Klasse können Sie eine Fabrik mit einer lokalen oder anonymen Klasse verwenden:
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);
}
Als pedantisch Notiz, Ihre static class Inner {}
ist technisch eine statische verschachtelte Klasse, keine innere Klasse.class Inner {}
(ohne static
) wäre eine innere Klasse.
Dies ist specifically defined so zu sein:
Das static
Schlüsselwort T
die Deklaration einer Elementtyp C
innerhalb des Körpers einer nicht-Innen Klasse oder Schnittstelle ändern kann. Sein Effekt ist zu erklären, dass C
keine innere Klasse ist.
Java-Zugriffsregeln sind kompliziert (noch mehr für 'protected'). aber wenn es funktioniert, sollten Sie glücklich sein, warum sich beschweren :) – ZhongYu