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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
<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,k100022.html;106,k100027.html;107,k100029.html;108,k100030.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="k100022.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100027.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100029.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100030.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 4 - Datentypen
</table>
<hr>
<!-- Section -->
<a name="abschnitttypkonvertierungen"></a>
<h2>4.6 <a name="ixa100314">Typkonvertierungen</a></h2>
<hr>
<ul>
<li><a href="k100028.html#abschnitttypkonvertierungen">4.6 Typkonvertierungen</a>
<ul>
<li><a href="k100028.html#sectlevel3id004006001">4.6.1 Standardkonvertierungen</a>
<li><a href="k100028.html#sectlevel3id004006002">4.6.2 Vorzeichenlose Bytes</a>
</ul>
</ul>
<hr>
<!-- Section -->
<a name="sectlevel3id004006001"></a>
<h3>4.6.1 Standardkonvertierungen </h3>
<p>
Es gibt diverse Konvertierungen zwischen unterschiedlichen Datentypen
in Java. Diese werden einerseits vom Compiler automatisch vorgenommen,
beispielsweise bei der Auswertung von numerischen Ausdrücken.
Andererseits können sie verwendet werden, um mit Hilfe des Type-Cast-Operators
(siehe <a href="k100030.html#kapitelausdruecke">Kapitel 5</a>) eigene
Konvertierungen vorzunehmen.
<p>
Java unterscheidet prinzipiell zwischen <a name="ixa100315"><i>erweiternden</i></a>
und <a name="ixa100316"><i>einschränkenden Konvertierungen</i></a>
und diese noch einmal nach primitiven Typen und Referenztypen. Zunächst
zu den Referenztypen:
<ul>
<li>Als erweiternde Konvertierung eines Referenztyps <font color="#000077"><tt>T</tt></font>
wird vor allem die Umwandlung eines Objekts vom Typ <font color="#000077"><tt>T</tt></font>
in eine seiner Vaterklassen angesehen.
<li>Als einschränkende Konvertierung eines Referenztyps <font color="#000077"><tt>T</tt></font>
wird vor allem die Umwandlung eines Objekts vom Typ <font color="#000077"><tt>T</tt></font>
in eine der aus <font color="#000077"><tt>T</tt></font> abgeleiteten
Klassen angesehen.
</ul>
<p>
Daneben gibt es noch eine ganze Reihe weiterer Regeln zur Definition
von erweiternden und einschränkenden Konvertierungen von Referenztypen.
Die Bedeutung von Vaterklassen und den daraus abgeleiteten Unterklassen
wird in <a href="k100051.html#kapiteloop2">Kapitel 8</a> ausführlich
erläutert.
<p>
<a name="ixa100317">Konvertierungen auf primitiven Datentypen</a>
sind etwas aufwändiger zu erklären. Wir benutzen dazu <a href="k100028.html#konvprimdatentypen">Abbildung 4.1</a>:
<p>
<a name="konvprimdatentypen"></a>
<img src="images/KonvPrimTyp.gif">
<p>
<p><i>
Abbildung 4.1: Konvertierungen auf primitiven Datentypen</i></p>
<p>
Jede Konvertierung, die in Pfeilrichtung erfolgt, beschreibt eine
erweiternde Konvertierung, und jede Konvertierung, die entgegen der
Pfeilrichtung erfolgt, beschreibt eine einschränkende Konvertierung.
Andere Konvertierungen zwischen primitiven Datentypen sind nicht erlaubt.
Insbesondere gibt es also keine legale Konvertierung von und nach
<a name="ixa100318"><a href="index_b.html#ixb100072"><font color=#000080><tt>boolean</tt></font></a></a>
und auch keine Konvertierung zwischen primitiven Typen und Referenztypen.
<p>
Welche Bedeutung haben nun aber die verschiedenen Konvertierungen
zwischen unterschiedlichen Typen? Wir wollen uns an dieser Stelle
lediglich mit den Konvertierungen zwischen primitiven Typen beschäftigen.
Wie aus <a href="k100028.html#konvprimdatentypen">Abbildung 4.1</a>
ersichtlich ist, beschränken sich diese auf Umwandlungen zwischen
numerischen Typen. Die Anwendung einer erweiternden Konvertierung
wird in folgenden Fällen vom Compiler automatisch vorgenommen:
<ul>
<li>Bei einer Zuweisung, wenn der Typ der Variablen und des zugewiesenen
Ausdrucks nicht identisch ist.
<li>Bei der Auswertung eines arithmetischen Ausdrucks, wenn Operanden
unterschiedlich typisiert sind.
<li>Beim Aufruf einer Methode, falls die Typen der aktuellen Parameter
nicht mit denen der formalen Parameter übereinstimmen.
</ul>
<p>
Es ist daher beispielsweise ohne weiteres möglich, ein <a href="index_s.html#ixb100243"><font color=#000080><tt>short</tt></font></a>
und ein <a href="index_i.html#ixb100244"><font color=#000080><tt>int</tt></font></a>
gemeinsam in einem Additionsausdruck zu verwenden, da ein <a href="index_s.html#ixb100243"><font color=#000080><tt>short</tt></font></a>
mit Hilfe einer erweiternden Konvertierung in ein <a href="index_i.html#ixb100244"><font color=#000080><tt>int</tt></font></a>
verwandelt werden kann. Ebenso ist es möglich, ein <a href="index_c.html#ixb100215"><font color=#000080><tt>char</tt></font></a>
als Array-Index zu verwenden, da es erweiternd in ein <a href="index_i.html#ixb100244"><font color=#000080><tt>int</tt></font></a>
konvertiert werden kann. Auch die Arithmetik in Ausdrücken, die
sowohl integrale als auch Fließkommawerte enthalten, ist möglich,
da der Compiler alle integralen Parameter erweiternd in Fließkommawerte
umwandeln kann.
<p>
Es ist dagegen nicht ohne weiteres möglich, einer <a href="index_i.html#ixb100244"><font color=#000080><tt>int</tt></font></a>-Variablen
einen <a href="index_d.html#ixb100247"><font color=#000080><tt>double</tt></font></a>-Wert
zuzuweisen. Die hierzu erforderliche einschränkende Konvertierung
nimmt der Compiler nicht selbst vor; sie kann allerdings mit Hilfe
des Type-Cast-Operators manuell durchgeführt werden. Auch die
Verwendung eines <a href="index_l.html#ixb100245"><font color=#000080><tt>long</tt></font></a>
als Array-Index verbietet sich aus diesem Grund.
<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>
Bei den einschränkenden Konvertierungen kann es passieren, dass
ein Wert verfälscht wird, da der Wertebereich des Zielobjekts
kleiner ist. Aber auch erweiternde Konvertierungen sind nicht immer
gefahrlos möglich. So kann zwar beispielsweise ein <a href="index_f.html#ixb100246"><font color=#000080><tt>float</tt></font></a>
mindestens genauso große Werte aufnehmen wie ein <a href="index_l.html#ixb100245"><font color=#000080><tt>long</tt></font></a>.
Seine Genauigkeit ist aber auf ca. 8 Stellen beschränkt, und
daher können größere Ganzzahlen (z.B. 1000000123)
nicht mehr mit voller Genauigkeit dargestellt werden.</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>
<!-- Section -->
<a name="sectlevel3id004006002"></a>
<h3>4.6.2 Vorzeichenlose Bytes </h3>
<p>
In Java sind alle numerischen Datentypen vorzeichenbehaftet. Das ist
in vielen Fällen sinnvoll, kann aber bei der Handhabung von 8-Bit-Bytes
hinderlich sein. Wird ein Byte als Repräsentation eines 8-Bit
langen Maschinenworts angesehen, will man meist den Wertebereich von
0 bis 255 zur Verfügung haben. Als vorzeichenbehafteter Datentyp
kann <a href="index_b.html#ixb100242"><font color=#000080><tt>byte</tt></font></a>
aber nur Werte von -128 bis 127 darstellen. Ein Wert größer
oder gleich 128 erfordert also mindestens ein <a href="index_s.html#ixb100243"><font color=#000080><tt>short</tt></font></a>
oder ein <a href="index_i.html#ixb100244"><font color=#000080><tt>int</tt></font></a>.
Deren Länge beträgt aber 2 bzw. 4 Byte.
<p>
Das Dilemma läßt sich dadurch auflösen, dass man zwischen
der programminternen Verarbeitung eines Bytes und seiner äußeren
Repräsentation unterscheidet. Die Repräsentation nach außen
erfolgt dabei mit dem Datentyp <a href="index_b.html#ixb100242"><font color=#000080><tt>byte</tt></font></a>.
Zur Verarbeitung im Programm wird er dagegen in ein <a href="index_i.html#ixb100244"><font color=#000080><tt>int</tt></font></a>
konvertiert, so dass alle Werte von 0 bis 255 dargestellt werden können.
Konvertierungsmethoden erlauben es, zwischen beiden Darstellungen
zu wechseln.
<p>
Natürlich gibt es keinerlei automatischen Schutz gegen Wertebereichsüberschreitungen,
wenn ein Byte als <a href="index_i.html#ixb100244"><font color=#000080><tt>int</tt></font></a>
verarbeitet wird. Dafür ist ausschließlich die Anwendung
selbst verantwortlich.
<p>
Das folgende Listing zeigt eine einfache Klasse <font color="#000077"><tt>ByteKit</tt></font>,
mit der zwischen beiden Darstellungen gewechselt werden kann:
<a name="listingid004012"></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">/**
<font color="#555555">002 </font> * ByteKit
<font color="#555555">003 </font> *
<font color="#555555">004 </font> * Einfache Klasse zur Umwandlung zwischen int, char und
<font color="#555555">005 </font> * vorzeichenlosen Bytes.
<font color="#555555">006 </font> */</font>
<font color="#555555">007 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> ByteKit
<font color="#555555">008 </font>{
<font color="#555555">009 </font> <font color="#00AA00">/**
<font color="#555555">010 </font> * Wandelt value (0 <= value <= 255) in ein byte um.
<font color="#555555">011 </font> */</font>
<font color="#555555">012 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">byte</font> fromUnsignedInt(<font color="#006699">int</font> value)
<font color="#555555">013 </font> {
<font color="#555555">014 </font> <font color="#0000AA">return</font> (<font color="#006699">byte</font>)value;
<font color="#555555">015 </font> }
<font color="#555555">016 </font>
<font color="#555555">017 </font> <font color="#00AA00">/**
<font color="#555555">018 </font> * Wandelt c in ein byte um. Das High-Byte wird ignoriert.
<font color="#555555">019 </font> */</font>
<font color="#555555">020 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">byte</font> fromChar(<font color="#006699">char</font> c)
<font color="#555555">021 </font> {
<font color="#555555">022 </font> <font color="#0000AA">return</font> (<font color="#006699">byte</font>)(c & 0xFF);
<font color="#555555">023 </font> }
<font color="#555555">024 </font>
<font color="#555555">025 </font> <font color="#00AA00">/**
<font color="#555555">026 </font> * Betrachtet value als vorzeichenloses byte und wandelt
<font color="#555555">027 </font> * es in eine Ganzzahl im Bereich 0..255 um.
<font color="#555555">028 </font> */</font>
<font color="#555555">029 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">int</font> toUnsignedInt(<font color="#006699">byte</font> value)
<font color="#555555">030 </font> {
<font color="#555555">031 </font> <font color="#0000AA">return</font> (value & 0x7F) + (value < 0 ? 128 : 0);
<font color="#555555">032 </font> }
<font color="#555555">033 </font>
<font color="#555555">034 </font> <font color="#00AA00">/**
<font color="#555555">035 </font> * Betrachtet value als vorzeichenloses byte und wandelt
<font color="#555555">036 </font> * es in ein Unicode-Zeichen mit High-Byte 0 um.
<font color="#555555">037 </font> */</font>
<font color="#555555">038 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">char</font> toChar(<font color="#006699">byte</font> value)
<font color="#555555">039 </font> {
<font color="#555555">040 </font> <font color="#0000AA">return</font> (<font color="#006699">char</font>)toUnsignedInt(value);
<font color="#555555">041 </font> }
<font color="#555555">042 </font>
<font color="#555555">043 </font> <font color="#00AA00">/**
<font color="#555555">044 </font> * Liefert die Binaerdarstellung von value.
<font color="#555555">045 </font> */</font>
<font color="#555555">046 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> String toBitString(<font color="#006699">byte</font> value)
<font color="#555555">047 </font> {
<font color="#555555">048 </font> <font color="#006699">char</font>[] chars = <font color="#0000AA">new</font> <font color="#006699">char</font>[8];
<font color="#555555">049 </font> <font color="#006699">int</font> mask = 1;
<font color="#555555">050 </font> <font color="#0000AA">for</font> (<font color="#006699">int</font> i = 0; i < 8; ++i) {
<font color="#555555">051 </font> chars[7 - i] = (value & mask) != 0 ? <font color="#0000FF">'1'</font> : <font color="#0000FF">'0'</font>;
<font color="#555555">052 </font> mask <<= 1;
<font color="#555555">053 </font> }
<font color="#555555">054 </font> <font color="#0000AA">return</font> <font color="#0000AA">new</font> String(chars);
<font color="#555555">055 </font> }
<font color="#555555">056 </font>}</pre>
</font>
</td>
<td valign=top align=right>
<a href="../examples/ByteKit.java"><font color="#000055" size=-1>ByteKit.java</font></a></td>
</tr>
</table>
<i>
Listing 4.12: Umwandlung zwischen int, byte und char</i></p>
<p>
Eine einfache Anwendung der Klasse <font color="#000077"><tt>ByteKit</tt></font>
zeigt das folgende Programm:
<a name="listingid004013"></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">/* Listing0413 */</font>
<font color="#555555">002 </font>
<font color="#555555">003 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing0413
<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">for</font> (<font color="#006699">int</font> i = 0; i < 256; ++i) {
<font color="#555555">008 </font> System.out.print(<font color="#0000FF">"i="</font> + i);
<font color="#555555">009 </font> <font color="#006699">byte</font> b = ByteKit.fromUnsignedInt(i);
<font color="#555555">010 </font> System.out.print(<font color="#0000FF">" b="</font> + ByteKit.toBitString(b));
<font color="#555555">011 </font> <font color="#006699">char</font> c = ByteKit.toChar(b);
<font color="#555555">012 </font> System.out.print(<font color="#0000FF">" c="</font> + (c >= 32 ? c : <font color="#0000FF">'.'</font>));
<font color="#555555">013 </font> System.out.println();
<font color="#555555">014 </font> }
<font color="#555555">015 </font> }
<font color="#555555">016 </font>}</pre>
</font>
</td>
<td valign=top align=right>
<a href="../examples/Listing0413.java"><font color="#000055" size=-1>Listing0413.java</font></a></td>
</tr>
</table>
<i>
Listing 4.13: Anwendung der Klasse ByteKit</i></p>
<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="k100022.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100027.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100029.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100030.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>
|