From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001
From: Sven Eisenhauer
+Zu jedem primitiven Datentyp in Java gibt es eine korrespondierende
+Wrapper-Klasse. Diese kapselt die primitive Variable in einer
+objektorientierten Hülle und stellt eine Reihe von Methoden zum
+Zugriff auf die Variable zur Verfügung. Zwar wird man bei der
+Programmierung meist die primitiven Typen verwenden, doch gibt es
+einige Situationen, in denen die Anwendung einer Wrapper-Klasse sinnvoll
+sein kann:
+
+Wrapper-Klassen existieren zu allen numerischen Typen und zu den Typen
+char
+und boolean:
+
+
+
+Tabelle 10.1: Die Wrapper-Klassen
+Die Instanzierung einer Wrapper-Klasse kann meist auf zwei unterschiedliche
+Arten erfolgen. Einerseits ist es möglich, den korrespondierenden
+primitiven Typ an den Konstruktor zu übergeben, um ein Objekt
+desselben Werts zu erzeugen. Alternativ kann meist auch ein String
+an den Konstruktor übergeben werden. Dieser wird in den entsprechenden
+primitiven Typ konvertiert und dann zur Initialisierung der Wrapper-Klasse
+verwendet.
+
+
+
+Das in diesem Beispiel mehrfach verwendete Schlüsselwort throws
+deklariert Ausnahmen, die während der Methodenausführung
+auftreten können. Sie entstehen durch Programmfehler, undefinierte
+Zustände oder treten auf, wenn unvorhergesehene Ereignisse eintreten
+(Datei nicht verfügbar, Speicher erschöpft oder ähnliches).
+Wir werden uns in Kapitel 12
+ausführlich mit diesem Thema beschäftigen.
+Die meisten Wrapper-Klassen besitzen zwei Methoden, um den internen
+Wert abzufragen. Eine der beiden liefert ihn passend zum korrespondierenden
+Grundtyp, die andere als String.
+Der Name von Methoden der ersten Art setzt sich aus dem Namen des
+Basistyps und der Erweiterung Value
+zusammen, beispielsweise charValue,
+booleanValue
+oder intValue.
+Die numerischen Methoden intValue,
+longValue,
+floatValue
+und doubleValue
+stehen dabei für alle numerischen Wrapper-Klassen zur Verfügung.
+
+
+Der Name der Methode, die den internen Wert als String
+zurückgibt, ist toString.
+Diese Methode steht in allen Wrapper-Klassen zur Verfügung:
+
+
+Ein einfaches Beispiel für die Anwendung der Wrapper-Klassen
+zeigt folgendes Listing:
+
+
+
+
+
+
+ Titel
+ Inhalt
+ Suchen
+ Index
+ DOC
+ Handbuch der Java-Programmierung, 5. Auflage
+
+ <<
+ <
+ >
+ >>
+ API
+ Kapitel 10 - OOP IV: Verschiedenes
+
+
+
+
+
+10.2 Wrapper-Klassen
+
+
+
+
+
+
+
+
+10.2.1 Vordefinierte Wrapper-Klassen
+
+
+
+
+
+
+
+
+
+Wrapper-Klasse
+Primitiver Typ
+
+Byte
+byte
+
+
+Short
+short
+
+
+Integer
+int
+
+
+Long
+long
+
+
+Double
+double
+
+
+Float
+float
+
+
+Boolean
+boolean
+
+
+Character
+char
+
+
+Void
+void
+ Instanzierung
+
+
+
+
+
+
+
+
+
+public Integer(int i)
+
+public Integer(String s)
+ throws NumberFormatException
+
+public Long(long l)
+
+public Long(String s)
+ throws NumberFormatException
+
+public Float(float f)
+
+public Float(double d)
+
+public Float(String s)
+ throws NumberFormatException
+
+public Double(double d)
+
+public Double(String s)
+ throws NumberFormatException
+
+public Boolean(boolean b)
+
+public Boolean(String s)
+
+public Character(char c)
+
+
+
+
+
+
+
+
+
+
+
+
+![]()
+
+
+
+![]()
+
+
+
+
+
+ Hinweis
+
+
Rückgabe des Wertes
+
+
+
+
+
+
+
+
+
+
+public boolean booleanValue()
+public char charValue()
+public int intValue()
+public long longValue()
+public float floatValue()
+public double doubleValue()
+
+
+
+
+
+
+
+
+
+
+
+public String toString()
+
+
+
+
+
+Listing 10.5: Anwendung der Wrapper-Klassen
+
+
+
+
+
+001 /* Listing1005.java */
+002
+003 public class Listing1005
+004 {
+005 public static void ohneAutoboxing(int arg)
+006 {
+007 Integer i = new Integer(arg);
+008 int j = i.intValue() + 1;
+009 System.out.println(i + " " + j);
+010 }
+011
+012 public static void main(String[] args)
+013 {
+014 ohneAutoboxing(17);
+015 }
+016 }
+
+
+Listing1005.java
+
+Die Methode ohneAutoboxing (warum
+sie so heißt, wird später deutlich werden) erzeugt einen
+Integer-Wrapper
+i aus dem als Argument übergebenen
+int.
+Dieser wird in einen int zurückkonvertiert
+und nach Addition von 1 der Variablen j
+zugewiesen. Anschließend werden beide Werte ausgegeben:
+
+
+17 18
+
+
+
+
+
+
+
+Neben der Möglichkeit, aus Strings Objekte zu erzeugen, können +die meisten Wrapper-Klassen auch primitive Datentypen erzeugen. Dazu +gibt es statische Methoden mit den Namen parseByte, +parseInt, +parseLong, +parseFloat +und parseDouble +in den zugehörigen Klassen Byte, +Integer, +Long, +Float +und Double: +
+
+
++public static byte parseByte(String s) + throws NumberFormatException + +public static int parseInt(String s) + throws NumberFormatException + +public static long parseLong(String s) + throws NumberFormatException + +public static float parseFloat(String s) + throws NumberFormatException + +public static double parseDouble(String s) + throws NumberFormatException ++ + |
+
+
![]() |
+![]() |
+
+
+ +Die Methoden parseFloat +und parseDouble +gibt es erst seit dem JDK 1.2. In älteren JDK-Versionen und den +meisten Web-Browsern stehen sie nicht zur Verfügung. |
+
+
|
+![]() |
+
+Die numerischen Wrapper-Klassen stellen Konstanten zur Bezeichnung +spezieller Elemente zur Verfügung. So gibt es in jeder der Klassen +Byte, +Short, +Integer, +Long, +Float +und Double +die Konstanten MIN_VALUE +und MAX_VALUE, +die das kleinste bzw. größte Element des Wertebereichs +darstellen. In den Klassen Float +und Double +gibt es zusätzlich die Konstanten NEGATIVE_INFINITY, +POSITIVE_INFINITY +und NaN. +Sie stellen die Werte minus unendlich, plus unendlich +und undefiniert dar. + + + + +
+Da Objektparameter im Gegensatz zu primitiven Typen per Referenz übergeben +werden, wären Wrapper-Klassen prinzipiell geeignet, Methodenparameter +per call by reference zu übergeben. +Damit könnten Änderungen von primitiven Parametern an den +Aufrufer zurückgegeben werden. In der Praxis funktioniert das +allerdings nicht, denn alle vordefinierten Wrapper-Klassen sind unveränderlich +(das wird auch als immutable bezeichnet). + +
+Sollen primitive Typen per Referenz übergeben werden, bieten +sich zwei Möglichkeiten an: +
+Beide Methoden sind nicht sehr elegant, werden aber in der Praxis +mitunter benötigt. Das folgende Listing zeigt, wie es gemacht +wird: + + +
+
+
+
+001 /* Listing1006.java */
+002
+003 class IntWrapper
+004 {
+005 public int value;
+006
+007 public IntWrapper(int value)
+008 {
+009 this.value = value;
+010 }
+011 }
+012
+013 public class Listing1006
+014 {
+015 public static void inc1(IntWrapper w)
+016 {
+017 ++w.value;
+018 }
+019
+020 public static void inc2(int[] i)
+021 {
+022 ++i[0];
+023 }
+024
+025 public static void main(String[] args)
+026 {
+027 //Variante 1: Übergabe in einem veränderlichen Wrapper
+028 IntWrapper i = new IntWrapper(10);
+029 System.out.println("i = " + i.value);
+030 inc1(i);
+031 System.out.println("i = " + i.value);
+032 //Variante 2: Übergabe als Array-Element
+033 int[] j = new int[] {10};
+034 System.out.println("j = " + j[0]);
+035 inc2(j);
+036 System.out.println("j = " + j[0]);
+037 }
+038 }
+
+ |
++Listing1006.java | +
+
![]() |
+![]() |
+
+
+ +Seit der J2SE 5.0 gibt es einen Mechanismus, der das automatische +Ein- und Auspacken von primitiven Typen in und aus Wrapper-Klassen +unterstützt. Dieses als Autoboxing +bzw. Autounboxing (»automatisches +Ein- und Auspacken«) bezeichnete Verfahren sorgt dafür, +dass an vielen Stellen automatisch zwischen primitiven Typen und Wrapperobjekten +konvertiert wird. Erwartet eine Methode beispielsweise einen Integer-Wert +als Argument, kann außer einem Integer +auch direkt ein int +übergeben werden; und er wird ohne Zutun des Entwicklers in einen +gleichwertigen Integer +konvertiert. Auch in umgekehrter Richtung funktioniert das, etwa wenn +in einem arithmetischen Ausdruck ein double +erwartet, aber ein Double +übergeben wird. |
+
+
|
+![]() |
+
+Das Beispiel aus Listing 10.5 +kann seit der J2SE 5.0 wie folgt vereinfacht werden: + + +
+
+
+
+001 /* Listing1007.java */
+002
+003 public class Listing1007
+004 {
+005 public static void mitAutoboxing(int arg)
+006 {
+007 Integer i = arg;
+008 int j = i + 1;
+009 System.out.println(i + " " + j);
+010 }
+011
+012 public static void main(String[] args)
+013 {
+014 mitAutoboxing(new Integer(17));
+015 }
+016 }
+
+ |
++Listing1007.java | +
+Die Einführung des Autoboxings und Autounboxings hat eine Vielzahl +von Auswirkungen auf die Java-Sprachspezifikation gebracht. Primitive +Typen und Wrapper-Objekte können nun in weiten Bereichen fast +gleichberechtigt benutzt werden. Die mitunter kritisierte, und in +manchen reinen OO-Sprachen (wie etwa Smalltalk) nicht vorhandene Unterscheidung +zwischen beiden Gruppen ist für die meisten praktischen Belange +nun irrelevant. + +
+So wird das Autoboxing etwa bei Zuweisungen und Methodenaufrufen angewandt, +wenn ein Wrapper-Objekt erwartet wird, aber nur ein primitiver Wert +zur Verfügung steht. Umgekehrt wird ein entsprechender Wrapper +bei Bedarf automatisch ausgepackt, wenn ein primitiver Wert erwartet, +aber ein Wrapper-Objekt übergeben wird. Auch innerhalb von Ausdrücken +können Wrapper-Objekte meist nahtlos anstelle von (und zusammen +mit) primitiven Werten verwendet werden. Ausnahme sind einige verändernde +Operatoren wie ++ und -- oder die kombinierten Zuweisungsoperatoren ++= oder -=. Wegen der Nebeneffekte können diese nicht auf (die +per Definition unveränderlichen) Wrapper-Objekte angewendet werden. +
+
![]() |
+
+
+ +Das obige Beispiel wirkt zugegebenermaßen etwas konstruiert. +Der wahre Nutzen des Autoboxings und Autounboxings kommt vor allem +in Synergie mit der erweiterten for-Schleife +und den typisierten Collections zum Tragen. Beispiele finden sich +etwa in Listing 15.10 +oder Listing 15.12. |
+
+
|
+![]() |
+
| Titel + | Inhalt + | Suchen + | Index + | DOC + | Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 + |
| << + | < + | > + | >> + | API + | © 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de + |