4.13.1 | Geschachtelte Top-Level-Klassen |
Geschachtelte Top-Level-Klassen oder -Interfaces sind wie die Paketbestandteile direkt für andere Klassen verfügbar. Es ist nicht erforderlich, zunächst ein Exemplar der umgebenden Klasse zu erzeugen.
Sie zeichnen sich dadurch aus, dass sie stets als static vereinbart werden. Im Gegensatz dazu sind die Paketbestandteile nie static. Die Definition von geschachtelten Top-Level-Klassen erfolgt entweder in einer Klasse, die Bestandteil eines Pakets ist, oder in einer anderen geschachtelten Top-Level-Klasse. Unter Berücksichtigung dieser Regel ist die Schachtelungstiefe beliebig. Geschachtelte Top-Level-Klassen können auch innerhalb von Interfaces vereinbart werden. Eine geschachtelte Top-Level-Klasse wird nach folgendem Muster vereinbart:package com.foo.mypackage; // MyClass ist "package member" public class MyClass { // Vereinbarung einer geschachtelten Top-Level-Klasse public static class NestedTopLevelClass { ... } }
static hat bei geschachtelten Top-Level-Klassen dieselbe Semantik wie bei Datenelementen und Methoden: Diese können ebenfalls ohne ein Exemplar der Klasse verwendet werden, in der sie definiert sind. Aus technischer Sicht stellen geschachtelte Top-Level-Klassen somit völlig eigenständige Klassen dar. Die Einbettung in eine andere Klasse erfolgt hauptsächlich aus Design-Gründen, um eine enge Assoziation der geschachtelten Top-Level-Klasse mit der umschließenden Klasse zum Ausdruck zu bringen.
Diese Assoziation hat nichts mit der »Verwandtschaft« zu tun, die sich durch Vererbung ergibt, wie am Ende des einführenden Abschnitts bemerkt wurde. Eine umschließende Klasse kann zwar von einer geschachtelten Top-Level-Klasse abgeleitet werden, jedoch wird man hiervon nur äußerst selten Gebrauch machen.
Wie die Paketbestandteile auch können geschachtelte Top-Level-Klassen mit den Modifiern abstract und public versehen werden. Geschachtelte Top-Level-Klassen dürfen nicht innerhalb von Blöcken definiert werden. Ferner dürfen Top-Level-Klassen, die in derselben Schachtelung stehen, gegenseitig auf ihre private-Bestandteile zugreifen.
Da geschachtelte Top-Level-Klassen im Gegensatz zu den anderen Arten von geschachtelten Klassen keine umschließenden Exemplare haben, können sie zunächst nur auf die statischen Bestandteile der umschließenden Klassen zugreifen. Nicht statische Bestandteile können nur angesprochen werden, wenn ein Exemplar einer umschließenden Klasse erzeugt und ein Verweis darauf übergeben wurde.
Das folgenden Beispiel zeigt eine Klasse Buffer, die einen Puffer auf Basis eines Arrays implementiert. Darin eingebettet ist die Klasse BufferIterator, die das Interface Enumeration implementiert. Mit ihr kann über den Pufferinhalt iteriert werden:public class Buffer { int[] buffer = new int[100]; public BufferIterator getIterator() { return new BufferIterator(buffer); } ... public static class BufferIterator implements Enumeration { private int[] buffer; int index; public BufferIterator(int[] buffer) { this.buffer = (int[])buffer.clone(); index = 0; } public boolean hasMoreElements() { return index < buffer.length; } public Object nextElement() { return new Integer(buffer[index++]); } } }
Eine geschachtelte Top-Level-Klasse muss entweder mit dem Paket und den Namen der umschließenden Klassen qualifiziert werden, oder man macht von der neuen Semantik der import-Anweisung Gebrauch.
Die Bedeutung von import wurde so erweitert, dass auch geschachtelte Top-Level-Klassen sichtbar gemacht werden können. Die Syntax ist hierbei dieselbe wie bei Paketbestandteilen. Eine geschachtelte Top-Level-Klasse NestedClass, die in einer Klasse MyClass im Paket mypackage vereinbart ist, kann mitimport mypackage.MyClass.MyNestedClass;sichtbar gemacht werden. Entsprechend können mitimport mypackage.MyClass.*;alle geschachtelten Top-Level-Klassen sichtbar gemacht werden, die in mypackage.MyClass definiert sind. Auch bei geschachtelten Top-Level-Klassen gilt für die Verwendung von import, dass die *-Notation nicht rekursiv wirkt. Wenn die Klasse MyNestedClass selbst wieder geschachtelte Top-Level-Klassen definiert, werden diese durch das letzte Beispiel nicht importiert.