Advanced Java Services | static member classes |
Bisher kennen wir statische Methoden und statische Daten in einer Klasse. Statische Daten existieren
pro Klasse genau einmal und sind nicht objektbezogen. Ganz genauso ist es mit statischen Memberklassen.
Wie andere Members auch, so können diese Klassen jeden beliebigen Schutzzustand haben.
// package xxx ; public class EnclosingClass { public static class PublicStaticMemberClass { } protected static class ProtectedStaticMemberClass { } static class DefaultStaticMemberClass { } private static class PrivateStaticMemberClass { } }
Das Beispiel zeigt vier statische nested Klassen mit allen möglichen Accessmodifiern.
Falls die Klasse EnclosingClass in einem eigenen Package verwendet wird, so sind neben der Klasse
EnclosingClass selbst nur die Klassen PublicStaticMemberClass und ProtectedStaticMemberClass außerhalb
des Packages bekannt, wobei auf letzere nur Unterklassen von EnclosingClass zugreifen dürfen. Die Klasse
DefaultStaticMemberClass hat dagegen den Defaultstatus und ist nur innerhalb des Packages bekannt, da
kein Accessmodifier explizit angegeben wird (siehe auch das Kapitel über
Packages). Die Klasse PrivateStaticMemberClass schließlich ist
nur innerhalb der Klasse EnclosingClass bekannt
Statische Memberklassen haben bezüglich ihres Innenlebens keinerlei Einschränkungen. Sie
dürfen alles, was eine "äußere" Klasse auch darf. Beim Zugriff auf die sie
einschließende Klasse gibt es lediglich die notwendige Einschränkung, daß aus einem
statischen Kontext heraus nicht auf nichtstatische Daten und Methoden zugegriffen werden kann. Das
folgende Beipiel demonstriert die wesentlichen Möglichkeiten von statischen inneren Klassen.
public class StaticDemo { private int a; public static int b; public StaticDemo() { System.out.println("Konstruktor StaticDemo"); StaticMemberClass2 smc = new StaticMemberClass2(); // 4 } public static void staticMethod() { System.out.println("äußere Methode"); } protected static class StaticMemberClass1 { private double x; // 1 public static int c ; public void innerNonstaticMethod() // 2 { } public static void innerStaticMethod() { } // anonymer konstruktor { //Verwendung äußerer Daten und Methoden // 3 b=17; staticMethod() ; //a = 17 ; // non-static variable a cannot be referenced from a static context } } private static class StaticMemberClass2 { StaticMemberClass1 smc = new StaticMemberClass1(); // 4 } } // end OuterClass1 class Drittklasse { StaticDemo smcd = new StaticDemo() ; // Anlegen eines Objektes vom Typ der statischen Memberklasse // 5 StaticDemo.StaticMemberClass1 smc1 = new StaticDemo.StaticMemberClass1() ; //StaticDemo.StaticMemberClass2 smc2 = new StaticDemo.StaticMemberClass2() ; //has private access //StaticDemo.StaticMemberClass1 smc1a = smcd.new StaticMemberClass1() ; // 6 //qualified new of static class //StaticDemo.StaticMemberClass1 smc1a = new smcd.StaticMemberClass1() ; //package smcd does not exist }
Die auskommentierten Anweisungen sind fehlerhaft. Die Fehlermeldungen des Compilers folgen jeweils in der nächsten Zeile. Die folgende Liste korrespondiert mit der Numerierung im obigen Beispiel.
Eine statische Memberklasse kann
Die einschließende Klasse kann
Eine dritte Klasse kann
Da die statischen Memberklassen für ihre Existenz kein Objekt der einschließenden Klasse brauchen zählt man sie zu den top-level Klassen. Die letzten beiden Punkte unterscheiden die statischen Memberklassen deutlich von den nichtstatischen Memberklassen, Letzere lassen sich nämlich nur über ein Objekt der umschließenden Klasse initialisieren und sind keine top-level Klassen (siehe non-static member classes und Übersichtstabelle der nested Klassen).
Statische innere Klasse sind keineswegs exotische Gebilde, sondern tauchen in der Klassenbibliothek immer wieder auf. Hier einige Beispiele.
Package | Umschließende Klasse | statische Memberklasse |
---|---|---|
javax.swing.text |
DefaultEditorKit |
public static class DefaultEditorKit.BeepAction |
public static class DefaultEditorKit.CopyAction | ||
public static class DefaultEditorKit.CutAction | ||
public static class DefaultEditorKit.DefaultKeyTypedAction | ||
public static class DefaultEditorKit.InsertBreakAction | ||
public static class DefaultEditorKit.InsertContentAction | ||
public static class DefaultEditorKit.InsertTabAction | ||
public static class DefaultEditorKit.PasteAction | ||
javax.swing.text.html |
HTML | public static class HTML.Attribute |
public static class HTML.Tag | ||
public static class HTML.UnknownTag | ||
javax.swing |
JFormattedTextField | public static abstract class JFormattedTextField.AbstractFormatter |
public static abstract class JFormattedTextField.AbstractFormatterFactory | ||
javax.swing |
JInternalFrame | public static class JInternalFrame.JDesktopIcon |
javax.swing |
JTree |
public static class JTree.DynamicUtilTreeNode |
protected static class JTree.EmptySelectionModel |