Advanced Java Services | Wrapperklassen (Hüllklassen) |
Angenommen, wir brauchen Platz für 6 (oder 66 oder 666) Variable vom Typ int. Kein Problem, dann besorgen wir uns ein Array der entsprechenden Größenordnung int arr[] = new int[6] etc. Es gibt allerdings Fälle, wo man vorher nicht weiß, wieviele Variable man braucht. Auch kein Problem. dafür gibt es schließlich die Klasse Vector, deren Objekte wachsen einfach im Hintergrund und man kann Objekte aufnehmen, solange es der Hauptspeicher mitmacht. Aber eben nur Objekte und keine primitiven int-Variablen. Also doch ein Problem ? Nein, denn dazu gibt es u.a. die Hüllklassen. Es gibt zu jedem primitiven Datentyp eine Hüllklasse. Mit ihr ist es möglich den Inhalt einer primitiven Variablen als Objekt darzustellen. Diese Hüllobjekte kann man dann problemlos etwa in ein Vectorobjekt aufnehmen.
primitiver Datentyp | Hüllklasse | Hüllkonstruktor | Stringkonstruktor |
---|---|---|---|
byte | Byte | Byte(byte value) | Byte(String s) |
short | Short | Short(short value) | Short(String s) |
int | Integer | Integer(int value) | Integer(String s) |
long | Long | Long(long value) | Long(String s) |
float | Float | Float(float value) | Float(String s) |
double | Double | Double(double value) | Double(String s) |
boolean | Boolean | Boolean(boolean value) | Boolean(String s) |
char | Character | Character(char value) | nicht vorhanden |
Jede Hüllklasse bietet einen Konstruktor an, aus dem man mit einer primitiven Variablen ein äquivalentes Hüllobjekt erzeugen kann. Bis auf Character haben alle Hüllklassen auch einen Konstruktor, der vesucht, aus einem String ein Hüllobjekt zu erzeugen. Dazu muß der String natürlich aus geeigneten Ziffern bestehen. Man kann dies als eine Art Datentypumwandlung sehen. Wir führen dies mit int bzw. Integer vor.
int a = 5 ; Integer wrapped_a = new Integer(a); // analog für byte, short, long, float, double, char, boolean
int a = 5 ; Integer wrapped_a = new Integer(a); int b = wrapped_a.intValue(); // analog byteValue(), shortValue(), longValue(), floatValue(), // doubleValue(), charValue(), booleanValue()
int a = 5 ; String string_a = ""+a ; // analog für byte, short, long, float, double, char, boolean // oder String string_a = Integer.toString(a) ; // analog für Byte, Short, Long, Float, Double, Character, Boolean
String string_a = "123" ; int a = Integer.parseInt(string_a); // analog parseByte(), parseShort(), parseLong(), parseFloat(), parseDouble(), // aber nicht für char oder boolean // für boolean String boost = "true" ; boolean boo = Boolean.getBoolean(boost) ; // für char String hola = "t" ; char ch = hola.charAt(0) ;
Integer wrapped = new Integer(69) ; String st69 = wrapped.toString() ; // analog für Byte, Short, Long, Float, Double, Character, Boolean
String st69 = "69"; Integer wrapped = new Integer(st69); // analog für Byte, Short, Long, Float, Double, Boolean // oder Integer wrapped = Integer.valueOf(st69); // analog für Byte, Short, Long, Float, Double, Boolean // für Character Character cha = new Character( st69.charAt(0) )
Bei der Umwandlung eines Strings in ein Boolean ergibt der String "trUE" unabhängig von der Groß- und Kleinschreibung den booleschen Wert true eingehüllt in ein Booleanobjekt, jeder andere String liefert ein eingehülltes false. Zudem kann man ein String nicht komplett in ein Characterobjekt verwandeln. Im Beispiel wird das erste Zeichen des Strings verwendet.
Hüllklasse | Umwandlungsmethoden |
---|---|
Byte |
static byte parseByte(String s) |
static byte parseByte(String s, int radix) | |
Short |
static short parseShort(String s) |
static short parseShort(String s, int radix) | |
Integer |
static int parseInt(String s) |
static int parseInt(String s, int radix) | |
Long |
static long parseLong(String s) |
static long parseLong(String s, int radix) |
Die einparametrigen parse-Methoden sehen einen String als Folge von Dezimalziffern und wandeln
diesen in eine Zahl zum entsprechenden primitiven Datentyp hin um. Falls der String nicht aus
Dezimalziffern besteht ist ein Umwandlung nicht möglich.
Die zweiparametrigen parse-Methoden sehen einen String als Folge von Ziffern zu einem Zahlensystem,
dessen Basis man mit dem zweiten Argument angibt. Falls der String nicht aus Ziffern des Zahlensystems
besteht ist ein Umwandlung nicht möglich.
Das folgende Beispiel definiert einen Hexstring und wandelt ihn in ein int um.
String hex = "abc" ; int hexzahl = Integer.parseInt(hex, 16) ;
Mit dieser Methode kann man aber auch Umrechnungen aus ungewöhnlichen Zahlensystemen erreichen.
Wir betrachten etwa das folgende Zahlensystem mit den Ziffern
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
Das ist ein Zahlensystem zur Basis 36 (10 herkömmliche Ziffern und die 26 Buchstaben des Alphabets).
String base36 = "zzz" ; int base36zahl = Integer.parseInt(base36, 36) ; System.out.println(base36zahl);
Es müßte sich die Zahl 35*362 + 35*361 + 35*360 = 46655 ergeben. Prüfen Sie es nach. Es stimmt.
Hüllklasse | Umwandlungsmethoden |
---|---|
Integer |
static String toBinaryString(int i) |
static String toOctalString(int i) | |
static String toHexString(int i) | |
Long |
static String toBinaryString(long l) |
static String toOctalString(long l) | |
static String toHexString(long l) |
Diese drei Methoden werden nur von Integer und Long angeboten. Als Beispiel stellen wir die Zahl 123 als Binärstring dar.
int a = 123 ; String binary = Integer.toBinaryString(a) ; System.out.println("123 = " + binary + " im Binaersystem");
Es ergibt sich die Ziffernfolge "1111011" .
Die Wrapperklassen besitzen zudem einige nützliche Konstanten, so kann man etwa mit Hilfe der folgenden Konstanten die Wertebereiche der primitiven Datentypen abfragen.
Hüllklasse | Wertebereichskonstanten |
---|---|
Byte |
static byte MIN_VALUE |
static byte MAX_VALUE | |
Short |
static short MIN_VALUE |
static short MAX_VALUE | |
Integer |
static int MIN_VALUE |
static int MAX_VALUE | |
Long |
static long MIN_VALUE |
static long MAX_VALUE | |
Float |
static float MIN_VALUE |
static float MAX_VALUE | |
Double |
static double MIN_VALUE |
static double MAX_VALUE |
Kommt es bei einer Ganzzahlrechnung zu einer Division durch 0, so erzeugt der Interpreter einen Laufzeitfehler und bricht das Programm ab. Nicht so bei einer Gleitkommarechnung, also bei einer Rechnung mit float oder double. In diesem Fall ergibt sich bei der Division einer Gleitkommazahl, die selbst nicht 0 ist durch 0 eine der INFINITY-Konstanten aus Float oder Double, je nachdem, ob der Zähler positiv oder negativ war.
Hüllklasse | INFINITY bzw. NaN Konstanten |
---|---|
Float |
static float NaN |
static float NEGATIVE_INFINITY | |
static float POSITIVE_INFINITY | |
Double |
static double NaN |
static double NEGATIVE_INFINITY | |
static double POSITIVE_INFINITY |
Die INFINITY-Konstanten sind verhältnismäßig einfach zu benützen. Jede double-Variable oder
double-Konstante ist mit den INFINITY-Konstanten aus Double vergleichbar (analog für float).
Auch sind die INFINITY-Konstanten mit sich selbst vergleicbar. Und alle diese Vergleiche
führen zu einem vernünftigen (logisch einwandfreien) Ergebnis.
Etwas verwickelter ist die Sache mit den beiden NaN-Konstanten (NaN steht für Not a Number).
Ein Vergleich mit double-Variablen oder double-Konstanten ist zwar möglich, liefert aber immer
false, was man auch einsieht. Hier geht es jedoch soweit, daß auch die folgende Vergleiche
stets false liefern:
Double.NaN == Double.POSITIVE_INFINITY | false |
Double.NaN == Double.NEGATIVE_INFINITY | false |
Double.NaN == Double.NaN | false |
Am Besten verwendet man die Nan-Konstanten nicht direkt sondern prüft ein Rechenergebnis
mit der statischen Methode
static boolean isNaN(double v)
So ergibt etwa der Aufruf von Double.isNaN(0.0/0.0) den Wert true .
Zahlen in einem Vector speichern
Das Zahlensystem wechseln