1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
<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,k100030.html;106,k100030.html;107,k100032.html;108,k100040.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="k100030.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100030.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100032.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100040.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 5 - Ausdrücke
</table>
<hr>
<!-- Section -->
<a name="sectlevel2id005001"></a>
<h2>5.1 Eigenschaften von Ausdrücken </h2>
<hr>
<ul>
<li><a href="k100031.html#sectlevel2id005001">5.1 Eigenschaften von Ausdrücken</a>
</ul>
<hr>
<p>
Wie in den meisten anderen Programmiersprachen gehören auch in
Java <i>Ausdrücke</i> zu den kleinsten ausführbaren Einheiten
eines Programms. Sie dienen dazu, Variablen einen Wert zuzuweisen,
numerische Berechnungen durchzuführen oder logische Bedingungen
zu formulieren.
<p>
Ein Ausdruck besteht immer aus mindestens einem Operator und einem
oder mehreren Operanden, auf die der Operator angewendet wird. Nach
den Typen der Operanden unterscheidet man <i>numerische</i>, <i>relationale</i>,
<i>logische</i>, <i>bitweise</i>, <i>Zuweisungs</i>- und <i>sonstige</i>
Operatoren. Jeder Ausdruck hat einen Rückgabewert, der durch
die Anwendung des Operators auf die Operanden entsteht. Der Typ des
Rückgabewerts bestimmt sich aus den Typen der Operanden und der
Art des verwendeten Operators.
<p>
Neben der Typisierung ist die <a name="ixa100319"><i>Stelligkeit eines Operators</i></a>
von Bedeutung. Operatoren, die lediglich ein Argument erwarten, nennt
man <i>einstellig</i>, solche mit zwei Argumenten <i>zweistellig</i>.
Beispiele für einstellige Operatoren sind das unäre Minus
(also das negative Vorzeichen) oder der logische Nicht-Operator. Arithmetische
Operatoren wie Addition oder Subtraktion sind zweistellig. Darüber
hinaus gibt es in Java - wie in C - auch den dreiwertigen Fragezeichenoperator.
<p>
Für die richtige Interpretation von Ausdrücken muss man
die <a name="ixa100320"><i>Bindungs</i></a>- und <a name="ixa100321"><i>Assoziativitätsregeln</i></a>
der Operatoren kennen. Bindungsregeln beschreiben die Reihenfolge,
in der verschiedene Operatoren innerhalb eines Ausdrucks ausgewertet
werden. So besagt beispielsweise die bekannte Regel »Punktrechnung
vor Strichrechnung«, dass der Multiplikationsoperator eine höhere
Bindungskraft hat als der Additionsoperator und demnach in Ausdrücken
zuerst ausgewertet wird. Assoziativität beschreibt die Auswertungsreihenfolge
von Operatoren derselben Bindungskraft, also beispielsweise die Auswertungsreihenfolge
einer Kette von Additionen und Subtraktionen. Da Summationsoperatoren
linksassoziativ sind, wird beispielsweise der Ausdruck <font color="#000077"><tt>a-b+c</tt></font>
wie <font color="#000077"><tt>(a-b)+c</tt></font> ausgewertet und
nicht wie <font color="#000077"><tt>a-(b+c)</tt></font>.
<p>
Neben ihrer eigentlichen Funktion, einen Rückgabewert zu produzieren,
haben einige Operatoren auch <a name="ixa100322"><i>Nebeneffekte</i></a>.
Als Nebeneffekt bezeichnet man das Verhalten eines Ausdrucks, auch
ohne explizite Zuweisung die Inhalte von Variablen zu verändern.
Meist sind diese Nebeneffekte erwünscht, wie etwa bei der Verwendung
der Inkrement- und Dekrementoperatoren. Komplexere Ausdrücke
können wegen der oftmals verdeckten Auswertungsreihenfolge der
Teilausdrücke jedoch unter Umständen schwer verständliche
Nebeneffekte enthalten und sollten deshalb mit Vorsicht angewendet
werden.
<p>
Im Gegensatz zu vielen anderen Programmiersprachen ist in Java die
<a name="ixa100323"><i>Reihenfolge der Auswertung</i></a> der Operanden
innerhalb eines Teilausdrucks wohldefiniert. Die Sprachdefinition
schreibt explizit vor, den linken Operanden eines Ausdrucks vollständig
vor dem rechten Operanden auszuwerten. Falls also beispielsweise <font color="#000077"><tt>i</tt></font>
den Wert 2 hat, dann ergibt der Ausdruck <font color="#000077"><tt>(i=3)
* i</tt></font> in jedem Fall den Wert 9 und nicht 6.
<p>
Neben der natürlichen Auswertungsreihenfolge, die innerhalb eines
Ausdrucks durch die Bindungs- und Assoziativitätsregeln vorgegeben
wird, läßt sich durch eine explizite <a name="ixa100324">Klammerung</a>
jederzeit eine andere Reihenfolge erzwingen. Während das Ergebnis
des Ausdrucks <font color="#000077"><tt>4+2*5</tt></font> wegen der
Bindungsregeln 14 ist, liefert <font color="#000077"><tt>(4+2)*5</tt></font>
das Resultat 30. Die Regeln für die Klammerung von Teilausdrücken
in Java gleichen denen aller anderen Programmiersprachen und brauchen
daher nicht weiter erläutert zu werden.
<p>
In Java gibt es ein Konzept, das sich <a name="ixa100325"><i>Definite Assignment</i></a>
nennt. Gemeint ist damit die Tatsache, dass jede lokale Variable vor
ihrer ersten Verwendung definitiv initialisiert sein muss. Das wünscht
sich eigentlich zwar auch jeder Programmierer, aber in Java wird dies
durch den Compiler sichergestellt! Dazu muss im Quelltext eine <a name="ixa100326">Datenflussanalyse</a>
durchgeführt werden, die jeden möglichen Ausführungspfad
von der Deklaration einer Variablen bis zu ihrer Verwendung ermittelt
und sicherstellt, dass kein Weg existiert, der eine Initialisierung
auslassen würde.
<p>
<p>
Die folgende Methode <font color="#000077"><tt>Test</tt></font> läßt
sich beispielsweise deshalb nicht fehlerfrei kompilieren, weil <font color="#000077"><tt>k</tt></font>
vor der Ausgabeanweisung nicht initialisiert wird, wenn <font color="#000077"><tt>i</tt></font>
kleiner 2 ist:
<a name="listingid005001"></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">static</font> <font color="#006699">void</font> Test(<font color="#006699">int</font> i)
<font color="#555555">002 </font>{
<font color="#555555">003 </font> <font color="#006699">int</font> k;
<font color="#555555">004 </font> <font color="#0000AA">if</font> (i >= 2) {
<font color="#555555">005 </font> k = 5;
<font color="#555555">006 </font> }
<font color="#555555">007 </font> System.out.println(k);
<font color="#555555">008 </font>}</pre>
</font>
</td>
</tr>
</table>
<i>
Listing 5.1: Fehler beim Kompilieren durch unvollständige Initialisierung</i></p>
<p>
Ein solches Verhalten des Compilers ist natürlich höchst
wünschenswert, denn es zeigt einen <i>tatsächlichen</i>
Fehler an, der sonst unbemerkt geblieben wäre. Daß die
Datenflussanalyse allerdings auch Grenzen hat, zeigt das folgende
Beispiel, bei dem ebenfalls ein Compiler-Fehler auftritt:
<a name="listingid005002"></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">static</font> <font color="#006699">void</font> Test(<font color="#006699">int</font> i)
<font color="#555555">002 </font>{
<font color="#555555">003 </font> <font color="#006699">int</font> k;
<font color="#555555">004 </font> <font color="#0000AA">if</font> (i < 2) {
<font color="#555555">005 </font> k = 5;
<font color="#555555">006 </font> }
<font color="#555555">007 </font> <font color="#0000AA">if</font> (i >= 2) {
<font color="#555555">008 </font> k = 6;
<font color="#555555">009 </font> }
<font color="#555555">010 </font> System.out.println(k);
<font color="#555555">011 </font>}</pre>
</font>
</td>
</tr>
</table>
<i>
Listing 5.2: Fehler beim Kompilieren durch unvollständige Datenflussanalyse</i></p>
<p>
Natürlich kann hier <font color="#000077"><tt>k</tt></font> nicht
uninitialisiert bleiben, denn eine der beiden Bedingungen ist immer
wahr. Leider gehen die Fähigkeiten der Compiler noch nicht so
weit, dies zu erkennen.
<p>
Es wäre in diesem Fall natürlich vernünftiger gewesen,
den <a href="index_e.html#ixb100172"><font color=#000080><tt>else</tt></font></a>-Zweig
an die erste Verzweigung anzuhängen und damit die zweite ganz
einzusparen.
<p>
In Wirklichkeit funktioniert die Datenflussanalyse bei vernünftigem
Programmierstil recht gut. Die wenigen Fälle, in denen der Compiler
sich irrt, können in der Regel durch explizite Initialisierungen
aufgelöst 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="k100030.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100030.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100032.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100040.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>
|