diff options
| author | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
|---|---|---|
| committer | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
| commit | 33613a85afc4b1481367fbe92a17ee59c240250b (patch) | |
| tree | 670b842326116b376b505ec2263878912fca97e2 /Master/Reference Architectures and Patterns/hjp5/html/k100065.html | |
| download | Studium-33613a85afc4b1481367fbe92a17ee59c240250b.tar.gz Studium-33613a85afc4b1481367fbe92a17ee59c240250b.tar.bz2 | |
Diffstat (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100065.html')
| -rw-r--r-- | Master/Reference Architectures and Patterns/hjp5/html/k100065.html | 542 |
1 files changed, 542 insertions, 0 deletions
diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100065.html b/Master/Reference Architectures and Patterns/hjp5/html/k100065.html new file mode 100644 index 0000000..a1ceeb8 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100065.html @@ -0,0 +1,542 @@ +<html>
+<head>
+<title>
+Handbuch der Java-Programmierung, 5. Auflage
+</title>
+</head>
+<body>
+<a name="startofbody"></a>
+<script language="JavaScript" src="hjp4lib.js">
+</script>
+<script language="JavaScript">
+installKbdHandler("97,#startofbody;101,#endofbody;116,cover.html;122,k100003.html;115,search.html;105,index.html;100,JDKDOCS;112,APIDOCS;104,k100064.html;106,k100064.html;107,k100066.html;108,k100070.html");
+</script>
+<table border=0 cellpadding=0 cellspacing=1 width="100%">
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
+<td align="right">Handbuch der Java-Programmierung, 5. Auflage
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100064.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100064.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100066.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100070.html"> >> </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
+<td align="right">Kapitel 10 - OOP IV: Verschiedenes
+</table>
+<hr>
+
+
+<!-- Section -->
+<a name="lokaleanonymeklassen"></a>
+<h2>10.1 Lokale und anonyme Klassen </h2>
+<hr>
+<ul>
+<li><a href="k100065.html#lokaleanonymeklassen">10.1 Lokale und anonyme Klassen</a>
+<ul>
+<li><a href="k100065.html#sectlevel3id010001001">10.1.1 Grundlagen</a>
+<li><a href="k100065.html#sectlevel3id010001002">10.1.2 Nicht-statische lokale Klassen</a>
+<ul>
+<li><a href="k100065.html#sectlevel4id010001002001">Klassen in Klassen</a>
+<li><a href="k100065.html#sectlevel4id010001002002">Klassen in Methoden</a>
+</ul>
+<li><a href="k100065.html#sectlevel3id010001003">10.1.3 Anonyme Klassen</a>
+<li><a href="k100065.html#sectlevel3id010001004">10.1.4 Statische lokale Klassen</a>
+</ul>
+</ul>
+<hr>
+
+
+<!-- Section -->
+<a name="sectlevel3id010001001"></a>
+<h3>10.1.1 Grundlagen </h3>
+
+<p>
+Bis zum JDK 1.0 wurden Klassen immer auf Paketebene definiert, eine
+Schachtelung war nicht möglich. Das hat die Compiler-Implementierung
+vereinfacht und die Struktur der Klassen innerhalb eines Pakets flach
+und übersichtlich gemacht. Unhandlich wurde dieses Konzept immer
+dann, wenn eine Klasse nur lokale Bedeutung hatte oder wenn »auf
+die Schnelle eine kleine Klasse« gebraucht wurde. Da es in Java
+keine Funktionszeiger gibt, besteht die einzige Möglichkeit,
+kleine Codebestandteile zwischen verschiedenen Programmteilen auszutauschen,
+darin, ein Interface zu deklarieren und die benötigte Funktionalität
+in einer implementierenden Klasse zur Verfügung zu stellen. Diese
+Technik wurde in <a href="k100061.html#fzeigerinterfaces">Abschnitt 9.4.3</a>
+vorgestellt.
+
+<p>
+Insbesondere bei den Erweiterungen für die Programmierung grafischer
+Oberflächen, die mit dem JDK 1.1 eingeführt wurden, entstand
+der Wunsch nach einem flexibleren Mechanismus. Durch das neue Ereignismodell
+(siehe <a href="k100180.html#kapiteleventhandling">Kapitel 28</a>)
+müssen seit dem JDK 1.1 sehr viel häufiger kleine Programmteile
+geschrieben werden, die nur in einem eng begrenzten Kontext eine Bedeutung
+haben. Die Lösung für dieses Problem wurde mit der Einführung
+von lokalen und anonymen Klassen geschaffen (im JDK werden sie als
+<a name="ixa100572"><i>Inner Classes</i></a> bezeichnet). Dabei wird
+innerhalb einer bestehenden Klasse X eine neue Klasse Y definiert,
+die nur innerhalb von X sichtbar ist. Objektinstanzen von Y können
+damit auch nur innerhalb von X erzeugt werden. Anders herum kann Y
+auf die Membervariablen von X zugreifen.
+
+<p>
+Lokale und anonyme Klassen sind ein mächtiges - und manchmal
+leicht verwirrendes - Feature von Java. Wir wollen nachfolgend seine
+wichtigsten Anwendungen vorstellen. Darüber hinaus gibt es seltener
+genutzte Varianten, die hauptsächlich durch trickreiche Anwendung
+von Modifiern auf die lokale Klasse oder ihrer Member entstehen. Auf
+diese wollen wir hier nicht weiter eingehen.
+
+<!-- Section -->
+
+<a name="sectlevel3id010001002"></a>
+<h3>10.1.2 Nicht-statische lokale Klassen </h3>
+
+
+<!-- Section -->
+<a name="sectlevel4id010001002001"></a>
+<h4>Klassen in Klassen </h4>
+
+<p>
+Die Definition einer nicht-statischen lokalen Klasse entspricht genau
+dem zuvor beschriebenen Grundprinzip: <i>innerhalb</i> des Definitionsteils
+einer beliebigen Klasse wird eine neue Klasse definiert. Ihre Instanzierung
+muss innerhalb der äußeren Klasse erfolgen, also in einer
+der Methoden der äußeren Klasse oder während ihrer
+Initialisierung. Die innere Klasse kann auf die Membervariablen der
+äußeren Klasse zugreifen und umgekehrt. Das folgende Listing
+illustriert dies an einem einfachen Beispiel:
+<a name="nichtstatischlokal"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing1001.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">class</font> Outer
+<font color="#555555">004 </font>{
+<font color="#555555">005 </font> String name;
+<font color="#555555">006 </font> <font color="#006699">int</font> number;
+<font color="#555555">007 </font>
+<font color="#555555">008 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> createAndPrintInner(String iname)
+<font color="#555555">009 </font> {
+<font color="#555555">010 </font> Inner inner = <font color="#0000AA">new</font> Inner();
+<font color="#555555">011 </font> inner.name = iname;
+<font color="#555555">012 </font> System.out.println(inner.getQualifiedName());
+<font color="#555555">013 </font> }
+<font color="#555555">014 </font>
+<font color="#555555">015 </font> <font color="#0000AA">class</font> Inner
+<font color="#555555">016 </font> {
+<font color="#555555">017 </font> <font color="#0000AA">private</font> String name;
+<font color="#555555">018 </font>
+<font color="#555555">019 </font> <font color="#0000AA">private</font> String getQualifiedName()
+<font color="#555555">020 </font> {
+<font color="#555555">021 </font> <font color="#0000AA">return</font> number + <font color="#0000FF">":"</font> + Outer.<font color="#006699">this</font>.name + <font color="#0000FF">"."</font> + name;
+<font color="#555555">022 </font> }
+<font color="#555555">023 </font> }
+<font color="#555555">024 </font>}
+<font color="#555555">025 </font>
+<font color="#555555">026 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing1001
+<font color="#555555">027 </font>{
+<font color="#555555">028 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">029 </font> {
+<font color="#555555">030 </font> Outer outer = <font color="#0000AA">new</font> Outer(); <a name="nichtstatischlokal.a"></a>
+<font color="#555555">031 </font> outer.name = <font color="#0000FF">"Outer"</font>;
+<font color="#555555">032 </font> outer.number = 77;
+<font color="#555555">033 </font> outer.createAndPrintInner(<font color="#0000FF">"Inner"</font>);
+<font color="#555555">034 </font> }
+<font color="#555555">035 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing1001.java"><font color="#000055" size=-1>Listing1001.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 10.1: Eine nicht-statische lokale Klasse</i></p>
+
+<p>
+Zunächst wird eine Klasse <font color="#000077"><tt>Outer</tt></font>
+mit den Membervariablen <font color="#000077"><tt>name</tt></font>
+und <font color="#000077"><tt>number</tt></font> definiert. Innerhalb
+von <font color="#000077"><tt>Outer</tt></font> wird dann eine Klasse
+<font color="#000077"><tt>Inner</tt></font> definiert. Sie besitzt
+eine eigene Membervariable <font color="#000077"><tt>name</tt></font>
+und eine Methode <font color="#000077"><tt>getQualifiedName</tt></font>.
+Beim Programmstart erzeugt <font color="#000077"><tt>main</tt></font>
+eine Instanz von <font color="#000077"><tt>Outer</tt></font> und initialisiert
+ihre Membervariablen. Anschließend ruft sie die Methode <font color="#000077"><tt>createAndPrintInner</tt></font>
+auf.
+
+<p>
+In <font color="#000077"><tt>createAndPrintInner</tt></font> wird
+nun eine Instanz von <font color="#000077"><tt>Inner</tt></font> erzeugt
+und mit dem als Argument übergebenen Namen initialisiert. Die
+Instanzierung erfolgt also im Kontext der äußeren Klasse,
+und diese kann auf die Membervariable der inneren Klasse zugreifen.
+In der Praxis wichtiger ist jedoch die Möglichkeit, die innere
+Klasse auf die Membervariablen der äußeren Klasse zugreifen
+zu lassen. Dadurch wird ihr der Status der äußeren Klasse
+zugänglich gemacht und sie kann Programmcode erzeugen (und durch
+die Kapselung in ein Objekt nötigenfalls an eine ganz andere
+Stelle im Programm transferieren), der Informationen aus der Umgebung
+der Klassendefinition verwendet. Um dies zu zeigen, ruft <font color="#000077"><tt>Outer</tt></font>
+nun die Methode <font color="#000077"><tt>getQualifiedName</tt></font>
+der inneren Klasse auf.
+
+<p>
+In <font color="#000077"><tt>getQualifiedName</tt></font> wird auf
+drei unterschiedliche Arten auf Membervariablen zugegriffen. Bei der
+Verwendung von <i>unqualifizierten</i> Namen (also solchen ohne Klassennamen-Präfix)
+werden <i>lexikalische</i> Sichtbarkeitsregeln angewandt. Der Compiler
+prüft also zunächst, ob es eine lokale Variable dieses Namens
+gibt. Ist das nicht der Fall, sucht er nach einer gleichnamige Membervariable
+in der aktuellen Klasse. Ist auch diese nicht vorhanden, erweitert
+er seine Suche sukzessive von innen nach außen auf alle umschließenden
+Klassen. Im Beispiel bezeichnet <font color="#000077"><tt>name</tt></font>
+also die gleichnamige Membervariable von <font color="#000077"><tt>Inner</tt></font>
+und <font color="#000077"><tt>number</tt></font> diejenige von <font color="#000077"><tt>Outer</tt></font>.
+Wird die Membervariable einer äußeren Klasse durch eine
+gleichnamige Membervariable der inneren Klasse verdeckt, kann über
+den Präfix »Klassenname.this.« auf die äußere
+Variable zugegriffen werden. Im Beispielprogramm wird das für
+die Variable <font color="#000077"><tt>name</tt></font> so gemacht.
+
+<p>
+Wird der Ausdruck »Klassenname.this« alleine verwendet,
+bezeichnet er das Objekt der äußeren Klasse, in der die
+aktuelle Instanz der inneren Klasse erzeugt wurde. In <font color="#000077"><tt>getQualifiedName</tt></font>
+würde <font color="#000077"><tt>Outer.this</tt></font> also die
+in <a href="k100065.html#nichtstatischlokal.a">Zeile 030</a> erzeugte
+Instanz <font color="#000077"><tt>outer</tt></font> bezeichnen.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Die Implementierung von lokalen Klassen konnte im JDK 1.1 ohne größere
+Änderungen der virtuellen Maschine vorgenommen werden. Lokale
+Klassen sind zwar zum Compilezeitpunkt bekannt, werden aber zur Laufzeit
+behandelt wie normale Klassen. Insbesondere wird vom Compiler zu jeder
+lokalen Klasse eine eigene <font color="#660099">.class</font>-Datei
+erzeugt. Um Überschneidungen zu vermeiden, besteht ihr Name aus
+dem Namen der äußeren Klasse, gefolgt von einem Dollarzeichen
+und dem Namen der inneren Klasse. Bei den später behandelten
+anonymen Klassen wird statt des Namens der inneren Klasse eine vom
+Compiler vergebene fortlaufende Nummer verwendet. Beim Übersetzen
+des vorigen Beispiels würden also die Klassendateien <font color="#660099">Outer.class</font>,
+<font color="#660099">Outer$Inner.class</font> und <font color="#660099">Listing1001.class</font>
+generiert.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="sectlevel4id010001002002"></a>
+<h4>Klassen in Methoden </h4>
+
+<p>
+Innere Klassen können nicht nur auf der äußersten
+Ebene einer anderen Klasse definiert werden, sondern auch innerhalb
+ihrer Methoden und sogar innerhalb eines beliebigen Blocks. In diesem
+Fall können sie auch auf die lokalen Variablen der umgebenden
+Methode oder des umgebenden Blocks zugreifen. Bedingung ist allerdings,
+dass diese mit Hilfe des Schlüsselworts <a href="index_f.html#ixb100401"><font color=#000080><tt>final</tt></font></a>
+als konstant deklariert wurden.
+
+<p>
+Diese Art, lokale Klassen zu definieren, ist nicht sehr gebräuchlich,
+taucht aber mitunter in fremdem Programmcode auf. In der Praxis werden
+an ihrer Stelle meist anonyme Klassen verwendet, wie sie im folgenden
+Abschnitt besprochen werden. Wir wollen uns dennoch ein einfaches
+Beispiel ansehen:
+<a name="listingid010002"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing1002.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">class</font> Outer2
+<font color="#555555">004 </font>{
+<font color="#555555">005 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> print()
+<font color="#555555">006 </font> {
+<font color="#555555">007 </font> <font color="#0000AA">final</font> <font color="#006699">int</font> value = 10;
+<font color="#555555">008 </font>
+<font color="#555555">009 </font> <font color="#0000AA">class</font> Inner2
+<font color="#555555">010 </font> {
+<font color="#555555">011 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> print()
+<font color="#555555">012 </font> {
+<font color="#555555">013 </font> System.out.println(<font color="#0000FF">"value = "</font> + value);
+<font color="#555555">014 </font> }
+<font color="#555555">015 </font> }
+<font color="#555555">016 </font>
+<font color="#555555">017 </font> Inner2 inner = <font color="#0000AA">new</font> Inner2();
+<font color="#555555">018 </font> inner.print();
+<font color="#555555">019 </font> }
+<font color="#555555">020 </font>}
+<font color="#555555">021 </font>
+<font color="#555555">022 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing1002
+<font color="#555555">023 </font>{
+<font color="#555555">024 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">025 </font> {
+<font color="#555555">026 </font> Outer2 outer = <font color="#0000AA">new</font> Outer2();
+<font color="#555555">027 </font> outer.print();
+<font color="#555555">028 </font> }
+<font color="#555555">029 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing1002.java"><font color="#000055" size=-1>Listing1002.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 10.2: Definition einer lokalen Klasse in einer Methode</i></p>
+
+
+<!-- Section -->
+<a name="sectlevel3id010001003"></a>
+<h3>10.1.3 Anonyme Klassen </h3>
+
+<p>
+Die häufigste Anwendung lokaler Klassen innerhalb von Methoden
+besteht darin, diese <i>anonym</i> zu definieren. Dabei erhält
+die Klasse keinen eigenen Namen, sondern Definition und Instanzierung
+erfolgen in einer kombinierten Anweisung. Eine anonyme Klasse ist
+also eine Einwegklasse, die nur einmal instanziert werden kann. Anonyme
+Klassen werden normalerweise aus anderen Klassen abgeleitet oder erweitern
+existierende Interfaces. Ihre wichtigste Anwendung finden sie bei
+der Definition von <i>Listenern</i> für grafische Oberflächen,
+auf die wir in <a href="k100180.html#kapiteleventhandling">Kapitel 28</a>
+noch ausführlich eingehen werden.
+
+<p>
+Als einfaches Anwendungsbeispiel wollen wir das in <a href="k100061.html#doublemethod">Listing 9.14</a>
+definierte Interface <font color="#000077"><tt>DoubleMethod</tt></font>
+noch einmal verwenden und zeigen, wie man beim Aufruf von <font color="#000077"><tt>printTable</tt></font>
+eine anonyme Klasse erzeugt und als Argument weitergibt:
+<a name="beispielanonymeklasse"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing1003.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing1003
+<font color="#555555">004 </font>{
+<font color="#555555">005 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> printTable(DoubleMethod meth)
+<font color="#555555">006 </font> {
+<font color="#555555">007 </font> System.out.println(<font color="#0000FF">"Wertetabelle "</font> + meth.toString());
+<font color="#555555">008 </font> <font color="#0000AA">for</font> (<font color="#006699">double</font> x = 0.0; x <= 5.0; x += 1) {
+<font color="#555555">009 </font> System.out.println(<font color="#0000FF">" "</font> + x + <font color="#0000FF">"->"</font> + meth.compute(x));
+<font color="#555555">010 </font> }
+<font color="#555555">011 </font> }
+<font color="#555555">012 </font>
+<font color="#555555">013 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">014 </font> {
+<font color="#555555">015 </font> printTable(
+<font color="#555555">016 </font> <font color="#0000AA">new</font> DoubleMethod() <a name="beispielanonymeklasse.a"></a>
+<font color="#555555">017 </font> {
+<font color="#555555">018 </font> <font color="#0000AA">public</font> <font color="#006699">double</font> compute(<font color="#006699">double</font> value)
+<font color="#555555">019 </font> {
+<font color="#555555">020 </font> <font color="#0000AA">return</font> Math.sqrt(value);
+<font color="#555555">021 </font> }
+<font color="#555555">022 </font> }
+<font color="#555555">023 </font> );
+<font color="#555555">024 </font> }
+<font color="#555555">025 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing1003.java"><font color="#000055" size=-1>Listing1003.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 10.3: Anwendung anonymer Klassen</i></p>
+
+<p>
+Statt eine vordefinierte Klasse zu instanzieren, wird hier in <a href="k100065.html#beispielanonymeklasse.a">Zeile 016</a>
+eine lokale anonyme Klasse definiert und instanziert. Syntaktisch
+unterscheidet sie sich von der Instanzierung einer vordefinierten
+Klasse dadurch, dass nach dem <font color="#000077"><tt>new KlassenName(...)</tt></font>
+nicht ein Semikolon, sondern eine geschweifte Klammer steht. Anschließend
+folgt die Definition der Klasse. Wird als Klassenname ein <i>Interface</i>
+angegeben, implementiert die anonyme Klasse dieses Interface. Handelt
+es sich dagegen um den Namen einer <i>Klasse</i>, wird die anonyme
+Klasse daraus abgeleitet. In unserem Beispiel wird das Interface <font color="#000077"><tt>DoubleMethod</tt></font>
+implementiert.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Das Programm hat durch die Verwendung der anonymen Klasse nicht unbedingt
+an Übersichtlichkeit gewonnen. Tatsächlich sind sowohl Nutzen
+als auch Syntax anonymer Klassen Gegenstand vieler Diskussionen gewesen.
+Der große Vorteil anonymer Klassen besteht in ihrer Flexibilität.
+Eine anonyme Klasse kann da deklariert werden, wo sie gebraucht wird
+(hier beispielsweise beim Aufruf von <font color="#000077"><tt>printTable</tt></font>).
+Zudem kann sie Code weitergeben, der auf lokale Variablen und Membervariablen
+ihrer unmittelbaren Umgebung zugreift.
+
+<p>
+Ihre Anwendung sollte sich auf die Fälle beschränken, in
+denen eine Klasse mit wenigen Zeilen Code erzeugt werden muss, die
+nur an einer bestimmten Programmstelle bedeutsam ist. Ist die Klasse
+umfangreicher oder wird sie an verschiedenen Stellen benötigt,
+sollte eine benannte Klasse definiert und an den Aufrufstellen instanziert
+werden.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="sectlevel3id010001004"></a>
+<h3>10.1.4 Statische lokale Klassen </h3>
+
+<p>
+Die letzte Variante innerer Klassen, die wir betrachten wollen, ist
+eigentlich gar keine. Hierbei wird eine Klasse innerhalb einer anderen
+Klasse definiert und mit dem Attribut <a href="index_s.html#ixb100422"><font color=#000080><tt>static</tt></font></a>
+versehen. In diesem Fall erzeugt der Compiler Code, der genau dem
+einer gewöhnlichen globalen Klasse entspricht. Insbesondere ist
+eine statische lokale Klasse nicht nur innerhalb der Klasse sichtbar,
+in der sie definiert wurde, sondern kann auch von außen instanziert
+werden. Sie hält auch keinen Verweis auf die instanzierende Klasse
+und kann somit nicht auf deren Membervariablen zugreifen. Der einzige
+Unterschied zu einer globalen Klasse besteht darin, dass der Name
+der inneren Klasse als Präfix den Namen der äußeren
+Klasse enthält. Beide sind durch einen Punkt voneinander getrennt.
+
+<p>
+Eine Klasse könnte beispielsweise dann als statische lokale Klasse
+definiert werden, wenn ihre Daseinsberechtigung auf der Existenz der
+äußeren Klasse basiert. Typische Anwendungen sind kleinere
+Hilfsklassen, die ausreichend Substanz zur Deklaration einer eigenen
+Klasse, aber zu wenig für eine eigene Datei haben. Durch den
+separaten Namensraum können sie auch Allerweltsnamen wie »Entry«,
+»Element« oder »Debug« haben.
+
+<p>
+Das folgende Listing zeigt eine einfache Anwendung statischer lokaler
+Klassen:
+<a name="listingid010004"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Listing1004.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">class</font> Outer3
+<font color="#555555">004 </font>{
+<font color="#555555">005 </font> <font color="#0000AA">static</font> <font color="#0000AA">class</font> Inner3
+<font color="#555555">006 </font> {
+<font color="#555555">007 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> print()
+<font color="#555555">008 </font> {
+<font color="#555555">009 </font> System.out.println(<font color="#0000FF">"Inner3"</font>);
+<font color="#555555">010 </font> }
+<font color="#555555">011 </font> }
+<font color="#555555">012 </font>}
+<font color="#555555">013 </font>
+<font color="#555555">014 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing1004
+<font color="#555555">015 </font>{
+<font color="#555555">016 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">017 </font> {
+<font color="#555555">018 </font> Outer3.Inner3 inner = <font color="#0000AA">new</font> Outer3.Inner3();
+<font color="#555555">019 </font> inner.print();
+<font color="#555555">020 </font> }
+<font color="#555555">021 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Listing1004.java"><font color="#000055" size=-1>Listing1004.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 10.4: Anwendung statischer lokaler Klassen</i></p>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Lokale und anonyme Klassen werden recht häufig eingesetzt. Auch
+in diesem Buch sind weitere Beispiele für ihre Anwendung zu finden.
+So wird beispielsweise in <a href="k100182.html#lokaleanonymeeventhandler">Abschnitt 28.2.2</a>
+erläutert, wie man sie zur Entwicklung von Ereignishandlern für
+GUI-Programme nutzen kann. </td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+<hr>
+<table border=0 cellpadding=0 cellspacing=1 width="100%">
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
+<td align="right">Handbuch der Java-Programmierung, 5. Auflage, Addison
+Wesley, Version 5.0.1
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100064.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100064.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100066.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100070.html"> >> </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
+<td align="right">© 1998, 2007 Guido Krüger & Thomas
+Stark, <a href="http://www.javabuch.de">http://www.javabuch.de</a>
+</table>
+<a name="endofbody"></a>
+</body>
+</html>
|
