Hüllklassen

<-- zurck zur Startseite | <- eine Seite vor | eine Seite weiter ->

  1. Was sind Hüllklassen?
  2. Abfragen des internen Wertes
  3. Konvertierung von Strings in primitive Datentypen
  4. Konvertierung in andere Zahlensysteme

1. Was sind Hüllklassen?

Da Java vollständig objektorientiert ist, gibt es selbst für die primitiven Datentypen übergeordnete Klassen. Diese Klassen heißen Hüllklassen (engl. "wrapper classes"). Sie kapseln die primitiven Datentypen in einer entsprechenden "Hülle" und sind da gefragt, wo man mit Variablen nicht weiterkommt, sondern Objekte braucht. Beispiele dafür werden wir noch kennen lernen, grundlegende Anwendungen werden in diesem Kapitel besprochen.
Folgende Hüllklassen kennt Java (definiert im Paket java.lang):

DatentypHüllklasseDatentypHüllklasse
booleanBoolean intInteger
byteByte longLong
shortShort floatFloat
charCharacter doubleDouble

Selbst für void gibt es eine zugehörige Hüllklasse namens Void. Wir wenden unseren Blick aber auf die in der Tabelle aufgeführten Hüllklassen. Diese besitzen, wie alle anderen Klassen, einen Konstruktor, mit dem ein Objekt der Klasse angelegt werden kann.

Integer zahl1 = new Integer(13);
Integer zahl2 = new Integer("13");

Zu beachten ist, dass man es jetzt nicht mehr mit primitiven Datentypen zu tun hat, sondern mit Objekten. Ergo ist die Variable nun nicht mehr vom Typ "int", sondern "Integer", also ein Objekt auf der Klasse "Integer". Der Konstruktor kann sowohl den korrespondierenden primitiven Datentyp (hier "int") als auch einen String, der dann in den entsprechenden Datentyp umgewandelt wird, verarbeiten. Exemplarisch wurde hier nur die Klasse "Integer" herausgegriffen, die Konstruktoren der anderen Hüllklassen arbeiten analog. Zu beachten ist, dass die Umwandlung eines Strings potenziell Fehler erzeugen kann und daher Ausnahmen (vom Typ NumberFormatException) auslösen kann.

nach oben

2. Abfragen des internen Wertes

Neben dem "Einhüllen" von primitiven Datentypen in Objekte kann auch der umgekehrte Weg gegangen werden und die internen Werte abgefragt werden. Dazu stellen die numerischen Hüllklassen (alle ausser "Boolean" und "Character") folgende Methoden bereit:

public byte byteValue()
public short shortValue()
public int intValue()
public long longValue()
public float floatValue()
public double doubleValue()

Wie man sieht, setzt sich der Methodenname aus dem primitiven Datentyp, der zurückgelieftert werden soll, und der Erweiterung "Value" zusammen, also z.B. intValue für "int". Diese Methoden sind nicht statisch und benötigen daher ein Objekt, zu dem sie aufgerufen werden. Bemerkenswert ist, dass alle diese Methoden in jeweils jeder numerischen Hüllklasse implementiert sind, d.h. den Inhalt eines "Double"-Objekts kann man sich z.B. mit der Methode "intValue" auch als Integer zurückgeben lassen. Die Hüllklassen Boolean und Character besitzen alle diese Methoden mit numerischen Rückgabewerten logischerweise nicht, dafür aber folgende:

public boolean booleanValue()
public char charValue()

Die Methode booleanValue existiert nur in der Klasse "Boolean" und gibt den internen Wert wieder als primitiven Datentyp "boolean" zurück. Entsprechendes gilt für die Methode charValue, die nur in der Klasse "Character" implementiert ist.

Die in allen Hüllklassen vorhandene Methode toString erlaubt es, den internen Wert als String abzuholen.

public String toString()

Ein kleines Beispiel zu den bisherigen Techniken (nur zur Veranschaulichung, bitte keine Diskussion über Sinnhaftigkeit beginnen):

Character zeichen = new Character('a');
Double zahl = new Double(3.14);
System.out.println("Zeichen: " + zeichen.toString());
System.out.println("Zahl: " + zahl.doubleValue());

nach oben

3. Konvertierung von Strings in primitive Datentypen

Bisher konnten wir nur primitive Datentypen in Strings umwandeln, der umgekehrte Weg war aber nicht möglich. Durch die Bereitstellung von Methoden, die gerade dies ermöglichen, kommen Hüllklassen sehr oft zum Einsatz. Dabei verfolgt Java den Ansatz, dass die zum Zieltyp korrespondierende Hüllklasse jeweils die Methode bereitstellt. So stellt die Klasse Integer die Methode parseInt für eine Konvertierung nach "int" zur Verfügung. Analog existiert die Methode parseByte in der Hüllklasse Byte, parseShort in Short, parseLong in Long, parseFloat in Float und parseDouble in Double. Der Name der Methode setzt sich aus "parse" und dem Namen des primitiven Datentyps, in den konvertiert werden soll, zusammen, also z.B. "parseInt" für eine Konvertierung nach "int". Diese Methoden sind statisch und können daher über den Klassennamen (ohne existierendes Objekt) angesprochen werden:

public static byte parseByte(String s)
public static short parseShort(String s)
public static int parseInt(String s)
public static long parseLong(String s)
public static float parseFloat(String s)
public static double parseDouble(String s)

Schlägt die Konvertierung fehl, wird jeweils eine Ausnahme vom Typ NumberFormatException ausgelöst.

Ein Beispiel zur Anwendung dieser Methoden:

String s1 = "4", s2 = "3.14";
int zahl1 = Integer.parseInt(s1);
double zahl2 = Double.parseDouble(s2);
System.out.println("Ergebnis: " + (zahl1*zahl2));

Leider hat die Sache noch einen kleinen Haken: die Methoden "parseFloat" und "parseDouble" stehen erst seit dem JDK1.2 zur Verfügung und können damit Beispielsweise in vielen Applets (noch) nicht verwendet werden, weil die meisten Browser noch mit Java1.1-Laufzeitumgebungen daherkommen. Will man sicher gehen, kann man einen kleinen Trick verwenden: man erzeugt zuerst ein Double-Objekt mit Hilfe der statischen Methode valueOf aus der Klasse "Double". Der primitive Datentyp, der in diesem Objekt "eingehüllt" ist, kann im nächsten Schritt mit der Methode doubleValue abgefragt werden. Beispiel:

String s1 = "4.1637", s2 = "true";
double doubleTest = Double.valueOf(s1).doubleValue();
boolean boolTest = Boolean.valueOf(s2).booleanValue();

Wie man an diesem Beispiel sieht, wurde wieder ein Kettenaufruf verwendet (siehe vorheriges Kapitel), da er uns Schreibarbeit erspart. Das Parsen eines "float"-Wertes erfolgt analog. Interessant ist außerdem, dass dies die einzige (!!) Möglichkeit ist, einen String in einen booleschen Wert zu verwandeln. Wird der Methode "valueOf" als String "true" oder "True" übergeben, so wird resultierenden Boolean-Objekt der boolesche Wert "true" gespeichert, in jedem anderen Fall (also auch bei sinnlosen Zeichenketten) "false". Dieser interne Wert kann ebenfalls mit der Methode "booleanValue" abgefragt werden.

nach oben

4. Konvertierung in andere Zahlensysteme

Obwohl die Hüllklassen bis jetzt schon praktisch genug sind, können sie noch mehr, nömlich Zahlen in andere Zahlensysteme überführen. Diese Technik soll beispielhaft an den Methoden der Hüllkasse "Integer" illustriert werden. Alle diese Methoden sind "static" und können daher über den Klassennamen angesprochen werden, ohne dass ein entsprechendes Integer-Objekt existieren muss (wie das bei den Methoden aus Abschnitt 2 der Fall ist):

public static String toString(int i, int sys)
public static String toBinaryString(int i)
public static String toHexString(int i)
public static int parseInt(String s, int sys)

Die Methode toString arbeitet anders als die gleichnamige Methode aus Abschnitt 2. Sie ist "static", also über den Klassennamen aufrufbar und erhält zwei Argumente: die Zahl, die in einen String konvertiert werden soll und die Basis des gewünschten Zahlensystems: bei Übergabe von 2 stellt der zurückgegebene String die Zahl in Dual-Schreibweise dar, 8 ergibt eine Darstellung im oktalen Zahlensystem und 16 erzwingt eine hexadezimale Schreibweise.
Etwas einfacher geht es mit den Methoden toBinaryString und toHexString: erstere gibt die Zahl als String in dualer (also binärer) Schreibweise zurück und letztere in hexadezimaler Darstellung. Das Ergebnis ist analog zum Aufruf von toString und der entsprechenden Basis des Zahlensystems.
Die Methode parseInt geht den umgekehrten Weg und wandelt einen String, der eine Zahl in einem bestimmten Zahlensystem darstellt, in eine Dezimalzahl um und gibt dieses als "int" zurück. Diese Methode unterscheidet sich von der gleichnamigen Methode aus Abschnitt 3 dadurch, dass sie ein zweites Argument erhält, nämlich wieder die Basis des Zahlensystems.
Folgendes kleines Beispiel demonstriert die Anwendung dieser Methoden:

int zahl = 57;
System.out.println("in dezimaler Schreibweise: " + zahl);
String oktal = Integer.toString(zahl, 8);
System.out.println("in oktaler Schreibweise: " + oktal);
String binaer = Integer.toBinaryString(zahl);
System.out.println("in binaerer Schreibweise: " + binaer);
String hexadezimal = Integer.toHexString(zahl);
System.out.println("in hexadezimaler Schreibweise: " + hexadezimal);
int zahl2 = Integer.parseInt(hexadezimal, 16);
System.out.println("nach Rueckwandlung aus hexadezimaler Schreibweise: " + zahl2);

Die Bildschirmausgabe dürfte für sich sprechen und die Funktionsweise der Methoden schön veranschaulichen:

screenshot

nach oben