diff options
Diffstat (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100044.html')
| -rw-r--r-- | Master/Reference Architectures and Patterns/hjp5/html/k100044.html | 661 |
1 files changed, 661 insertions, 0 deletions
diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100044.html b/Master/Reference Architectures and Patterns/hjp5/html/k100044.html new file mode 100644 index 0000000..dd0c017 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100044.html @@ -0,0 +1,661 @@ +<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,k100040.html;106,k100043.html;107,k100045.html;108,k100046.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="k100040.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100043.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100045.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100046.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 6 - Anweisungen
+</table>
+<hr>
+
+
+<!-- Section -->
+<a name="sectlevel2id006004"></a>
+<h2>6.4 Sonstige Anweisungen </h2>
+<hr>
+<ul>
+<li><a href="k100044.html#sectlevel2id006004">6.4 Sonstige Anweisungen</a>
+<ul>
+<li><a href="k100044.html#assertanweisung">6.4.1 Die assert-Anweisung</a>
+<ul>
+<li><a href="k100044.html#sectlevel4id006004001001">Syntax</a>
+<li><a href="k100044.html#sectlevel4id006004001002">Bedeutung</a>
+<li><a href="k100044.html#sectlevel4id006004001003">An- und Abschalten der Assertions</a>
+<li><a href="k100044.html#sectlevel4id006004001004">Anwendungen</a>
+<li><a href="k100044.html#sectlevel4id006004001005">Nebeneffekte</a>
+<li><a href="k100044.html#sectlevel4id006004001006">Kompatibilität</a>
+</ul>
+</ul>
+</ul>
+<hr>
+
+
+<!-- Section -->
+<a name="assertanweisung"></a>
+<h3>6.4.1 Die <a name="ixa100422">assert-Anweisung</a> </h3>
+<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 Ausführungen in diesem Abschnitt können beim ersten
+Lesen übersprungen werden. Bei der <a name="ixa100423"><a href="index_a.html#ixb100056"><font color=#000080><tt>assert</tt></font></a></a>-Anweisung
+handelt es sich um ein weiterführendes Konzept, das seit dem
+JDK 1.4 zur Verfügung steht. Neben einem grundlegenden Verständnis
+von Klassen und Methoden (ab <a href="k100046.html#kapiteloop1">Kapitel 7</a>)
+setzt es insbesondere Kenntnisse über das Auslösen und Behandeln
+von Ausnahmen voraus, die erst in <a href="k100078.html#kapitelexceptions">Kapitel 12</a>
+vermittelt werden. Aus systematischen Gründen soll das Thema
+jedoch an dieser Stelle behandelt 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="sectlevel4id006004001001"></a>
+<h4>Syntax </h4>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
+<tr>
+<td valign=top width=100%>
+<font color="#660066">
+<pre>
+assert ausdruck1 [ : ausdruck2 ] ;
+</pre>
+</font>
+</td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="sectlevel4id006004001002"></a>
+<h4>Bedeutung </h4>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=1></td>
+<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Seit dem JDK 1.4 gibt es in Java eine <a href="index_a.html#ixb100056"><font color=#000080><tt>assert</tt></font></a>-Anweisung.
+Diese, ursprünglich schon für die erste JDK-Version vorgesehene,
+dann aber aus Zeitgründen zurückgestellte Anweisung wird
+C- oder C++-Programmierern wohlbekannt sein. Sie dient dazu, an einer
+bestimmten Stelle im Programmablauf einen logischen Ausdruck zu platzieren,
+von dem der Programmierer annimmt, dass er stets <i>wahr</i> ist.
+Ist das der Fall, fährt das Programm mit der nächsten Anweisung
+fort, andernfalls wird eine Ausnahme des Typs <a name="ixa100424"><a href="index_a.html#ixb100360"><font color=#000080><tt>AssertionError</tt></font></a></a>
+ausgelöst. Ein solcher Ausdruck wird auch als <a name="ixa100425"><i>Invariante</i></a>
+bezeichnet, denn er bleibt unverändert <a href="index_t.html#ixb100233"><font color=#000080><tt>true</tt></font></a>,
+solange das Programm korrekt funktioniert.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#FF9900">
+<tr>
+<td><font color="#FFFFFF"> JDK1.1-6.0 </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+<p>
+<i>Assertions</i>, wie <a href="index_a.html#ixb100056"><font color=#000080><tt>assert</tt></font></a>-Anweisungen
+vereinfachend genannt werden, dienen also dazu, bestimmte Annahmen
+über den Zustand des Programms zu verifizieren und sicherzustellen,
+dass diese eingehalten werden. Soll im Programm beispielsweise überprüft
+werden, ob eine Variable <font color="#000077"><tt>x</tt></font> nicht-negativ
+ist, könnte dazu die folgende <a href="index_a.html#ixb100056"><font color=#000080><tt>assert</tt></font></a>-Anweisung
+verwendet werden:
+<font color="#000077">
+<pre>
+assert x >= 0;
+</pre>
+</font>
+
+<p>
+Das Programm überprüft die Bedingung und fährt fort,
+wenn sie erfüllt ist. Andernfalls wird eine Ausnahme ausgelöst.
+Natürlich hätte derselbe Test auch mit Hilfe einer einfachen
+<a href="index_i.html#ixb100075"><font color=#000080><tt>if</tt></font></a>-Anweisung
+ausgeführt werden können. Die <a href="index_a.html#ixb100056"><font color=#000080><tt>assert</tt></font></a>-Anweisung
+hat ihr gegenüber jedoch einige Vorteile:
+<ul>
+<li>Der Programmcode ist kürzer.
+<li>Auf den ersten Blick ist zu erkennen, dass es sich um einen Korrektheits-Check
+handelt und nicht um eine Verzweigung zur Steuerung des Programmablaufs.
+<li>Assertions lassen sich zur Laufzeit wahlweise an- oder ausschalten.
+Im Gegensatz zu einer einfachen <a href="index_i.html#ixb100075"><font color=#000080><tt>if</tt></font></a>-Anweisung
+verursachen sie praktisch keine Verschlechterung des Laufzeitverhaltens,
+wenn sie deaktiviert sind.
+</ul>
+
+<p>
+Der im Syntaxdiagramm angegebene <font color="#000077"><tt>ausdruck1</tt></font>
+muss immer vom Typ <a href="index_b.html#ixb100072"><font color=#000080><tt>boolean</tt></font></a>
+sein, andernfalls gibt es einen Compilerfehler. Fehlt <font color="#000077"><tt>ausdruck2</tt></font>
+(er darf von beliebigem Typ sein), wird im Falle des Nichterfülltseins
+der Bedingung ein <a href="index_a.html#ixb100360"><font color=#000080><tt>AssertionError</tt></font></a>
+mit einer <i>leeren</i> Fehlermeldung erzeugt. Wurde <font color="#000077"><tt>ausdruck2</tt></font>
+dagegen angegeben, wird er im Fehlerfall an den Konstruktor von <a href="index_a.html#ixb100360"><font color=#000080><tt>AssertionError</tt></font></a>
+übergeben und dient als Meldungstext für das Fehlerobjekt.
+
+
+<!-- Section -->
+<a name="sectlevel4id006004001003"></a>
+<h4>An- und Abschalten der Assertions </h4>
+
+<p>
+Aus Kompatibilität zu älteren JDK-Versionen sind Assertions
+sowohl im Compiler als auch im Interpreter standardmäßig
+deaktiviert. Um einen Quellcode zu übersetzen, der Assertions
+enthält, kann dem Java-Compiler ab der Version 1.4 die Option
+<a name="ixa100426"><a href="index_0.html#ixb100153"><font color=#000080><tt>-source 1.4</tt></font></a></a>
+(ab der J2SE 5.0 auch <a href="index_0.html#ixb100154"><font color=#000080><tt>-source 1.5</tt></font></a>)
+übergeben werden. Wird dies nicht gemacht, gibt es eine Fehlermeldung,
+nach der »assert« ein Schlüsselwort ist und nicht mehr
+als Bezeichner verwendet werden darf. Ältere Compilerversionen
+melden einen Syntaxfehler. Wir wollen uns ein einfaches Beispielprogramm
+ansehen:
+<a name="anwendungassertions"></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">/* AssertionTest.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> AssertionTest
+<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> main(String[] args)
+<font color="#555555">006 </font> {
+<font color="#555555">007 </font> <font color="#0000AA">assert</font> args.length >= 2; <a name="anwendungassertions.a"></a>
+<font color="#555555">008 </font> <font color="#006699">int</font> i1 = Integer.parseInt(args[0]);
+<font color="#555555">009 </font> <font color="#006699">int</font> i2 = Integer.parseInt(args[1]);
+<font color="#555555">010 </font> <font color="#0000AA">assert</font> i2 != 0 : <font color="#0000FF">"Teilen durch 0 nicht moeglich"</font>; <a name="anwendungassertions.b"></a>
+<font color="#555555">011 </font> System.out.println(i1 + <font color="#0000FF">"/"</font> + i2 + <font color="#0000FF">"="</font> + (i1/i2));
+<font color="#555555">012 </font> }
+<font color="#555555">013 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/AssertionTest.java"><font color="#000055" size=-1>AssertionTest.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 6.9: Anwendung von Assertions</i></p>
+
+<p>
+Das Beispielprogramm verwendet zwei Assertions, um sicherzustellen,
+dass mindestens zwei Kommandozeilenargumente übergeben werden
+und dass das zweite von ihnen nicht 0 ist. Es kann mit folgendem Kommando
+übersetzt werden, wenn der Compiler mindestens die Version 1.4
+hat:
+<font color="#333300">
+<pre>
+javac -source 1.4 AssertionTest.java
+</pre>
+</font>
+
+<p>
+Um das Programm laufen zu lassen, kennt der Java-Interpreter ab der
+Version 1.4 die Kommandozeilenoptionen <a name="ixa100427"><a href="index_0.html#ixb100362"><font color=#000080><tt>-enableassertions</tt></font></a></a>
+und <a name="ixa100428"><a href="index_0.html#ixb100363"><font color=#000080><tt>-disableassertions</tt></font></a></a>,
+die mit <a name="ixa100429"><a href="index_0.html#ixb100364"><font color=#000080><tt>-ea</tt></font></a></a>
+bzw. <a name="ixa100430"><a href="index_0.html#ixb100365"><font color=#000080><tt>-da</tt></font></a></a>
+abgekürzt werden können. Ihre Syntax lautet:
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
+<tr>
+<td valign=top width=100%>
+<font color="#660066">
+<pre>
+java [ -enableassertions | -ea ] [:PaketName... | :KlassenName ]
+
+java [ -disableassertions | -da ] [:PaketName... | :KlassenName ]
+</pre>
+</font>
+</td>
+</tr>
+</table>
+
+<p>
+Werden die Optionen ohne nachfolgenden Paket- oder Klassennamen angegeben,
+werden die Assertions für alle Klassen mit Ausnahme der Systemklassen
+<font color="#000077"><tt>java.*</tt></font> an- bzw. ausgeschaltet.
+Wird, durch einen Doppelpunkt getrennt, ein Klassenname angegeben,
+gilt die jeweilige Option nur für diese Klasse. Wird ein Paketname
+angegeben (von einem Klassennamen durch drei angehängte Punkte
+zu unterscheiden), erstreckt sich die Option auf alle Klassen innerhalb
+des angegebenen Pakets. Die Optionen können mehrfach angegeben
+werden, sie werden der Reihe nach ausgewertet. Wird keine dieser Optionen
+angegeben, sind die Assertions deaktiviert.
+
+<p>
+Soll unser Beispielprogramm mit aktivierten Assertions ausgeführt
+werden, kann also folgendes Kommando verwendet werden:
+<font color="#333300">
+<pre>
+java -ea AssertionTest
+</pre>
+</font>
+
+<p>
+In diesem Fall gibt es sofort eine Fehlermeldung, denn die erste <a href="index_a.html#ixb100056"><font color=#000080><tt>assert</tt></font></a>-Anweisung
+ist nicht erfüllt. Rufen wir das Programm mit zwei Zahlen als
+Argumente auf, wird erwartungsgemäß deren Quotient berechnet:
+<font color="#333300">
+<pre>
+java -ea AssertionTest 100 25
+</pre>
+</font>
+
+<p>
+Die Ausgabe lautet:
+<font color="#333300">
+<pre>
+100/25=4
+</pre>
+</font>
+
+<p>
+Wenn das zweite Argument dagegen 0 ist, gibt es eine Fehlermeldung,
+weil die zweite Assertion nicht erfüllt ist. Auch in diesem Fall
+steigt das Programm mit einem <a href="index_a.html#ixb100360"><font color=#000080><tt>AssertionError</tt></font></a>
+aus, der zusätzlich die Fehlermeldung »Teilen durch 0 nicht
+moeglich« enthält, die wir nach dem Doppelpunkt in <a href="k100044.html#anwendungassertions.b">Zeile 010</a>
+angegeben haben:
+<font color="#333300">
+<pre>
+Exception in thread "main" java.lang.AssertionError:
+ Teilen durch 0 nicht moeglich
+...
+</pre>
+</font>
+
+<p>
+Wird das Programm mit deaktivierten Assertions aufgerufen, verhält
+es sich, als wären die Zeilen <a href="k100044.html#anwendungassertions.a">007</a>
+und <a href="k100044.html#anwendungassertions.b">010</a> gar nicht
+vorhanden. In diesem Fall gibt es die üblichen Laufzeitfehler,
+die bei einem Zugriff auf ein nicht vorhandenes Array-Element oder
+die Division durch 0 entstehen.
+
+<!-- Section -->
+
+<a name="sectlevel4id006004001004"></a>
+<h4>Anwendungen </h4>
+
+<p>
+Genau genommen war das vorige Programm kein wirklich gutes Beispiel
+für die Anwendung von Assertions. Das Überprüfen der
+an ein Programm übergebenen Kommandozeilenparameter sollte nämlich
+besser einer <a name="ixa100431"><a href="index_i.html#ixb100366"><font color=#000080><tt>IllegalArgumentException</tt></font></a></a>
+überlassen werden:
+<a name="listingid006010"></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="#0000AA">public</font> <font color="#0000AA">class</font> Listing0610
+<font color="#555555">002 </font>{
+<font color="#555555">003 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
+<font color="#555555">004 </font> {
+<font color="#555555">005 </font> <font color="#0000AA">if</font> (args.length < 2) {
+<font color="#555555">006 </font> <font color="#0000AA">throw</font> <font color="#0000AA">new</font> IllegalArgumentException();
+<font color="#555555">007 </font> }
+<font color="#555555">008 </font> ...
+<font color="#555555">009 </font> }
+<font color="#555555">010 </font>}</pre>
+</font>
+</td>
+</tr>
+</table>
+<i>
+Listing 6.10: Verwendung einer IllegalArgumentException</i></p>
+
+<p>
+Genau wie bei der Übergabe eines Arguments an eine öffentliche
+Methode sollte es nicht einfach möglich sein, deren Überprüfung
+zur Laufzeit abzuschalten. Da ein Programm bei der Übergabe von
+Werten an öffentliche Schnittstellen keinerlei Annahmen darüber
+machen kann, ob diese Werte korrekt sind, sollte die Überprüfung
+dieser Werte immer aktiv sein. Die Verwendung von Assertions empfiehlt
+sich also in diesem Fall nicht. Weitere Beispiele für derartige
+öffentliche Schnittstellen sind etwa die Daten, die über
+eine grafische Benutzerschnittstelle in ein Programm gelangen oder
+die aus Dateien oder über Netzwerkverbindungen eingelesen werden.
+In all diesen Fällen sollten nicht-abschaltbare Fehlerprüfungen
+anstelle von Assertions verwendet werden.
+
+<p>
+Der Einsatz von Assertions ist dagegen immer dann sinnvoll, wenn Daten
+aus unbekannten Quellen bereits verifiziert sind. Wenn also das Nichterfülltsein
+einer Assertion einen Programmfehler anzeigt und nicht fehlerhafte
+Eingabedaten. Beispiele sind:
+<ul>
+<li>Die Überprüfung von Parametern, die an nicht-öffentliche
+Methoden übergeben werden. Diese können nur dann falsch
+sein, wenn das <i>eigene Programm</i> sie fehlerhaft übergibt.
+Kann nach dem Test der Software davon ausgegangen werden, dass ein
+bestimmter Codeteil fehlerfrei ist, ist es legitim, die Assertions
+in diesem Bereich zu deaktivieren und so die Performance des Programms
+zu verbessern. Innerhalb der Test- und Debugphase dagegen sind die
+Assertions eine große Hilfe beim Aufdecken von verdeckten Fehlern.
+<li>Die Verwendung in <a name="ixa100432"><i>Postconditions</i></a>,
+also in Bedingungen, die <i>am Ende einer Methode</i> erfüllt
+sein müssen. Postconditions dienen dazu, sicherzustellen, dass
+eine Methode bei korrekten Eingabewerten (die ihrerseits durch <a name="ixa100433"><i>Preconditions</i></a>
+abgesichert werden) auch korrekte Ergebnisse produziert. Beispielsweise
+könnte am Ende der <font color="#000077"><tt>push</tt></font>-Methode
+eines Stacks sichergestellt werden, dass der Stack nicht-leer ist.
+<li>Die Überprüfung von <a name="ixa100434"><i>Schleifeninvarianten</i></a>,
+also von Bedingungen, die am Anfang oder Ende einer Schleife <i>bei
+jedem</i> Schleifendurchlauf erfüllt sein müssen. Dies ist
+besonders bei Schleifen sinnvoll, die so komplex sind, dass beim Programmieren
+eine Art »Restunsicherheit« bezüglich ihrer Korrektheit
+bestehen bleibt.
+<li>Die Markierung von »toten Zweigen« in <a href="index_i.html#ixb100075"><font color=#000080><tt>if</tt></font></a>-
+oder <a href="index_c.html#ixb100350"><font color=#000080><tt>case</tt></font></a>-Anweisungen,
+die normalerweise niemals erreicht werden sollten. Anstatt hier einen
+Kommentar der Art »kann niemals erreicht werden« zu platzieren,
+könnte auch eine Assertion mit <a href="index_f.html#ixb100234"><font color=#000080><tt>false</tt></font></a>
+als Argument gesetzt werden. Wird dieser Zweig später tatsächlich
+einmal aufgrund eines Programmfehlers durchlaufen, geschieht dies
+wenigstens nicht unerkannt, sondern das Programm liefert eine Fehlermeldung
+und zeigt den Ort des Problems an.
+</ul>
+<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>
+Sowohl Pre- als auch Postconditions wurden mit der Programmiersprache
+<a name="ixa100435"><i>Eiffel</i></a>, die Bertrand Meyer <a name="ixa100436"></a>
+in seinem Buch »Object-oriented Software Construction« 1988
+vorgestellt hat, einer breiteren Öffentlichkeit bekannt. Das
+im JDK 1.4 implementierte Assertion-Konzept entspricht allerdings
+nicht in allen Aspekten Meyer's ausgefeiltem »Programming by
+Contract«. Dort gibt es beispielsweise explizite Schlüsselwörter
+für Pre- und Postconditions, und es ist möglich, in Postconditions
+auf den »alten« Wert eines Parameters zuzugreifen (also
+auf den, den er beim Eintritt in die Methode hatte).</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>
+
+<p>
+Dennoch stellen Assertions ein wichtiges Hilfsmittel dar, um Programme
+zuverlässiger und besser lesbar zu machen. Das folgende Programm
+zeigt verschiedene Anwendungen von Assertions am Beispiel einer einfachen
+Klasse zur Speicherung von Listen von Ganzzahlen:
+<a name="simpleintlist"></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="#0000AA">public</font> <font color="#0000AA">class</font> SimpleIntList
+<font color="#555555">002 </font>{
+<font color="#555555">003 </font> <font color="#0000AA">private</font> <font color="#006699">int</font>[] data;
+<font color="#555555">004 </font> <font color="#0000AA">private</font> <font color="#006699">int</font> len;
+<font color="#555555">005 </font>
+<font color="#555555">006 </font> <font color="#0000AA">public</font> SimpleIntList(<font color="#006699">int</font> size)
+<font color="#555555">007 </font> {
+<font color="#555555">008 </font> <font color="#006699">this</font>.data = <font color="#0000AA">new</font> <font color="#006699">int</font>[size];
+<font color="#555555">009 </font> <font color="#006699">this</font>.len = 0;
+<font color="#555555">010 </font> }
+<font color="#555555">011 </font>
+<font color="#555555">012 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> add(<font color="#006699">int</font> value)
+<font color="#555555">013 </font> {
+<font color="#555555">014 </font> <font color="#00AA00">//Precondition als RuntimeException</font>
+<font color="#555555">015 </font> <font color="#0000AA">if</font> (full()) { <a name="simpleintlist.f"></a>
+<font color="#555555">016 </font> <font color="#0000AA">throw</font> <font color="#0000AA">new</font> RuntimeException(<font color="#0000FF">"Liste voll"</font>);
+<font color="#555555">017 </font> }
+<font color="#555555">018 </font> <font color="#00AA00">//Implementierung</font>
+<font color="#555555">019 </font> data[len++] = value;
+<font color="#555555">020 </font> <font color="#00AA00">//Postcondition</font>
+<font color="#555555">021 </font> <font color="#0000AA">assert</font> !empty(); <a name="simpleintlist.a"></a>
+<font color="#555555">022 </font> }
+<font color="#555555">023 </font>
+<font color="#555555">024 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> bubblesort()
+<font color="#555555">025 </font> {
+<font color="#555555">026 </font> <font color="#0000AA">if</font> (!empty()) {
+<font color="#555555">027 </font> <font color="#006699">int</font> cnt = 0;
+<font color="#555555">028 </font> <font color="#0000AA">while</font> (<font color="#006699">true</font>) {
+<font color="#555555">029 </font> <font color="#00AA00">//Schleifeninvariante</font>
+<font color="#555555">030 </font> <font color="#0000AA">assert</font> cnt++ < len: <font color="#0000FF">"Zu viele Iterationen"</font>; <a name="simpleintlist.b"></a>
+<font color="#555555">031 </font> <font color="#00AA00">//Implementierung...</font>
+<font color="#555555">032 </font> <font color="#006699">boolean</font> sorted = <font color="#006699">true</font>;
+<font color="#555555">033 </font> <font color="#0000AA">for</font> (<font color="#006699">int</font> i = 1; i < len; ++i) {
+<font color="#555555">034 </font> <font color="#0000AA">if</font> (sortTwoElements(i - 1, i)) {
+<font color="#555555">035 </font> sorted = <font color="#006699">false</font>;
+<font color="#555555">036 </font> }
+<font color="#555555">037 </font> }
+<font color="#555555">038 </font> <font color="#0000AA">if</font> (sorted) {
+<font color="#555555">039 </font> <font color="#0000AA">break</font>;
+<font color="#555555">040 </font> }
+<font color="#555555">041 </font> }
+<font color="#555555">042 </font> }
+<font color="#555555">043 </font> }
+<font color="#555555">044 </font>
+<font color="#555555">045 </font> <font color="#0000AA">public</font> <font color="#006699">boolean</font> empty()
+<font color="#555555">046 </font> {
+<font color="#555555">047 </font> <font color="#0000AA">return</font> len <= 0;
+<font color="#555555">048 </font> }
+<font color="#555555">049 </font>
+<font color="#555555">050 </font> <font color="#0000AA">public</font> <font color="#006699">boolean</font> full()
+<font color="#555555">051 </font> {
+<font color="#555555">052 </font> <font color="#0000AA">return</font> len >= data.length;
+<font color="#555555">053 </font> }
+<font color="#555555">054 </font>
+<font color="#555555">055 </font> <font color="#0000AA">private</font> <font color="#006699">boolean</font> sortTwoElements(<font color="#006699">int</font> pos1, <font color="#006699">int</font> pos2)
+<font color="#555555">056 </font> {
+<font color="#555555">057 </font> <font color="#00AA00">//Private Preconditions</font>
+<font color="#555555">058 </font> <font color="#0000AA">assert</font> (pos1 >= 0 && pos1 < len); <a name="simpleintlist.c"></a>
+<font color="#555555">059 </font> <font color="#0000AA">assert</font> (pos2 >= 0 && pos2 < len); <a name="simpleintlist.d"></a>
+<font color="#555555">060 </font> <font color="#00AA00">//Implementierung...</font>
+<font color="#555555">061 </font> <font color="#006699">boolean</font> ret = <font color="#006699">false</font>;
+<font color="#555555">062 </font> <font color="#0000AA">if</font> (data[pos1] > data[pos2]) {
+<font color="#555555">063 </font> <font color="#006699">int</font> tmp = data[pos1];
+<font color="#555555">064 </font> data[pos1] = data[pos2];
+<font color="#555555">065 </font> data[pos2] = tmp;
+<font color="#555555">066 </font> ret = <font color="#006699">true</font>;
+<font color="#555555">067 </font> }
+<font color="#555555">068 </font> <font color="#00AA00">//Postcondition</font>
+<font color="#555555">069 </font> <font color="#0000AA">assert</font> data[pos1] <= data[pos2] : <font color="#0000FF">"Sortierfehler"</font>; <a name="simpleintlist.e"></a>
+<font color="#555555">070 </font> <font color="#0000AA">return</font> ret;
+<font color="#555555">071 </font> }
+<font color="#555555">072 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/SimpleIntList.java"><font color="#000055" size=-1>SimpleIntList.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 6.11: Anwendung von Assertions</i></p>
+
+<p>
+Precondition-Assertions sind in den Zeilen <a href="k100044.html#simpleintlist.c">058</a>
+und <a href="k100044.html#simpleintlist.d">059</a> zu sehen. Sie stellen
+sicher, dass die Methode mit gültigen Array-Indizes aufgerufen
+wird. Eine Precondition, die als <a href="index_r.html#ixb100372"><font color=#000080><tt>RuntimeException</tt></font></a>
+implementiert wurde, findet sich in <a href="k100044.html#simpleintlist.f">Zeile 015</a>
+und prüft, ob die Liste vor dem Einfügen eines weiteren
+Elements bereits voll ist. Während die Postcondition in <a href="k100044.html#simpleintlist.a">Zeile 021</a>
+eher formaler Natur ist, überprüft jene in <a href="k100044.html#simpleintlist.e">Zeile 069</a>,
+ob das Sortieren der Elemente tatsächlich erfolgreich war. Die
+Schleifeninvariante in <a href="k100044.html#simpleintlist.b">Zeile 030</a>
+stellt sicher, dass der Bubblesort nicht zu viele Arraydurchläufe
+macht, was ein Indiz dafür wäre, dass er in eine Endlosschleife
+geraten wäre.
+
+<!-- Section -->
+
+<a name="sectlevel4id006004001005"></a>
+<h4>Nebeneffekte </h4>
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=1></td>
+<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Normalerweise sollten die Ausdrücke in Assertions keine Nebeneffekte
+enthalten. Also keinen Code, der Variablen verändert oder den
+Status des Programms auf andere Weise modifiziert. Der Grund dafür
+ist, dass diese Nebeneffekte bei abgeschalteten Assertions natürlich
+nicht ausgeführt werden. Das Programm würde sich also anders
+verhalten, als wenn die Assertions angeschaltet wären. Dadurch
+können sehr schwer zu findende Fehler entstehen. Generell gilt,
+dass die Funktionalität des Programms nicht davon abhängen
+sollte, ob die Assertions an- oder abgeschaltet sind.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#CC0000">
+<tr>
+<td><font color="#FFFFFF"> Warnung </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+<p>
+Allerdings kann es berechtigte Ausnahmen geben. Ein Gegenbeispiel
+liefert etwa das vorige Listing in <a href="k100044.html#simpleintlist.b">Zeile 030</a>.
+Hier wird innerhalb der Assertion die Zählervariable <font color="#000077"><tt>cnt</tt></font>
+inkrementiert, also eine Variable verändert. Das ist allerdings
+unkritisch, denn diese wird auch nur innerhalb der Assertion benötigt,
+spielt ansonsten im Programm aber keine Rolle. Variablen, die auch
+an anderen Stellen im Programm verwendet werden, sollten allerdings
+nicht innerhalb von Assertions verändert werden.
+
+<!-- Section -->
+
+<a name="sectlevel4id006004001006"></a>
+<h4>Kompatibilität </h4>
+
+<p>
+Wie schon erwähnt, gibt es Assertions erst seit der Version 1.4
+des JDK. Ihre Verwendung wirft leider einige Kompatibilitätsprobleme
+auf:
+<ul>
+<li>Ein Quelltext, der <a href="index_a.html#ixb100056"><font color=#000080><tt>assert</tt></font></a>-Anweisungen
+enthält, kann nur mit einem Compiler übersetzt werden, der
+mindestens die Version 1.4 unterstützt. Ältere Compiler
+halten eine <a href="index_a.html#ixb100056"><font color=#000080><tt>assert</tt></font></a>-Anweisung
+für eine Schlüsselwort und melden einen Syntaxfehler. Das
+Gleiche passiert, wenn der JDK-1.4-oder-höher-Compiler ohne die
+Option <a href="index_0.html#ixb100153"><font color=#000080><tt>-source 1.4</tt></font></a>
+aufgerufen wird, nur ist dann die Fehlermeldung klarer.
+<li>Bytecode von Klassen, die <a href="index_a.html#ixb100056"><font color=#000080><tt>assert</tt></font></a>-Anweisungen
+enthalten, läßt sich nicht auf älteren virtuellen
+Maschinen ausführen, denn die vom Compiler generierten Zugriffe
+auf Felder und Klassen sind dort nicht vorhanden.
+</ul>
+
+<p>
+Was folgt daraus? Assertions lassen sich nur dann sinnvoll einsetzen,
+wenn der Entwickler mindestens einen JDK-1.4.Compiler besitzt <i>und</i>
+davon ausgehen kann, dass auf allen Zielsystemen, für die er
+entwickelt, ein mindestens 1.4-kompatibles Laufzeitsystem vorhanden
+ist. Letzteres ist mitunter nicht unbedingt der Fall. Der Reiz von
+Java liegt ja gerade in seiner Plattformunabhängigkeit, und bis
+auf allen wichtigen Zielsystemen ein JDK-1.4-Laufzeitsystem zur Verfügung
+stehen wird und auch installiert ist, könnte es noch einige Zeit
+dauern. Wegen der zur Installation eines neueren JDKs oft erforderlichen
+Betriebssystempatches auf UNIX- oder Host-Systemen sind noch immer
+viele derartige Systeme mit älteren JDKs ausgestattet.
+
+<p>
+<b>Fazit</b>: Assertions sind ein ausgezeichnetes Mittel, um Code
+lesbarer und robuster zu gestalten. Während der Debugphase helfen
+sie bei der Fehlersuche. Sofern keine Kompatibilität zu älteren
+JDK-Versionen erforderlich ist, sollten sie daher unbedingt verwendet
+werden. Kann dagegen nicht sichergestellt werden, dass die Zielsysteme
+mindestens das JDK 1.4 unterstützen, können Assertions nicht
+verwendet werden.
+<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="k100040.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100043.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100045.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100046.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>
|
