Typumwandlung
Type-Casting mit primitiven Datentypen
Man unterscheidet zwischen einer expliziten und einer impliziten Typumwandlung. Die implizite Typumwandlung findet automatisch bei der Zuweisung statt. Dies geht jedoch nur, wenn ein niederwertiger Datentyp in einen höher wertigen Datentypen umgewandelt wird, also z.B. vom Datentyp int in den Datentyp long.
Beispiel:
int wert = 10; long wert2 = 30; /* impliziteTypumwandlung ohne cast-Operator: der int-Wert wird in einen long-Wert umgewandelt (gecastet) */ wert2 = wert;
Bei der Datentypumwandlung spricht man auch von einem Typecast. Die explizite Umwandlung erfolgt durch den sogenannten cast-Operator. Hier wird von einem höher wertigen Datentyp in einen nieder wertigen Datentypen umgewandelt. In welchen Datentyp umgewandelt werden soll, muss bei dem cast Operator explizit angegeben werden. Sehen wir uns hierzu wieder ein Beispiel an.
Beispiel:
int wert = 10; float wert2 = 30.5f; /* expliziteTypumwandlung mit cast-Operator: der float-Wert wird in einen int-Wert umgewandelt (gecastet) */ wert = ( int ) wert2;
In dem obigen Beispiel ist (int) der cast Operator. Er gibt an, dass der folgende Wert in den Datentyp int umgewandelt werden soll. Bei der Typumwandlung von einem höher wertigen Datentyp in einen nieder wertigen Datentyp kann ein Genauigkeitsverlust stattfinden. Dies ist z.B. in unserem Beispiel der Fall, da die Nachkommastellen abgeschnitten werden. Man muss also vor jedem Cast überlegen, ob man einen Genauigkeitsverlust hinnehmen will oder nicht.
In den folgenden Übersichten sehen Sie, welche Typumwandlungen überhaupt möglich sind.
Beispiel 1:
// lokale Variablen char posChar, negChar; short posShort = 1; short negShort = -1; /* explizite Typumwandlung von dem Datentyp short in den Datentyp char */ posChar = (char) posShort; negChar = (char) negShort; // Ausgabe der expliziten Typumwandlung von oben System.out.println("positiver Short " + posShort + " ist als Char " + posChar); System.out.println("negativer Short " + negShort + " ist als Char " + negChar); /* Ausgabe der erneuten expliziten Typumwandlung, diesmal von char nach int */ System.out.println("positiver Short " + posShort +" ist als Char " + (int) posChar); System.out.println("negativer Short " + negShort + " ist als Char " + (int) negChar);
Was könnte ausgegeben werden?
Kleiner Hinweis: Nehmen Sie sich eine Ascii-Tabelle zu Hilfe.
Beispiel 2:
// lokale Variablen char bigChar, smallChar; int smallInt = 65535; int bigInt = 65536; /* explizite Typumwandlung von dem Datentyp int in den Datentyp char */ smallChar = (char) smallInt ; bigChar = (char) bigInt ; // Ausgabe der expliziten Typumwandlung von oben System.out.println("kleiner Int " + smallInt + " ist als Char " + smallChar); System.out.println("großer Int " + bigInt + " ist als Char " + bigChar); /* Ausgabe der erneuten expliziten Typumwandlung dieses mal von char nach int */ System.out.println("kleiner Int " + smallInt + " ist als Char " + (int) smallChar); System.out.println("großer Int " + bigInt + " ist als Char " + (int) bigChar);
Wie könnte hier die Ausgabe lauten?
Kleiner Hinweis: Nehmen Sie sich eine Ascii-Tabelle zu Hilfe.
Beispiel 3:
// lokale Variablen double myDouble1 = 2147483642d; double myDouble2 = 2147483647d; double myDouble3 = 2147483648d; int myInt1, myInt2, myInt3; /* explizite Typumwandlung von dem Datentyp double in den Datentyp int */ myInt1= (int) myDouble1; myInt2= (int) myDouble2; myInt3= (int) myDouble3; // Ausgabe der expliziten Typumwandlung von oben System.out.println("Double " + myDouble1 + " wird zu " + myInt1); System.out.println("Double" + myDouble2 + " wird zu " + myInt2); System.out.println("Double " + myDouble3 + " wird zu " + myInt3);
Wie könnte hier die Ausgabe lauten?
Beispiel 4:
// lokale Variablen double smallDouble = 9.999999999d; double bigDouble = 1.23E145d; /* explizite Typumwandlung von dem Datentyp double in den Datentyp float */ float smallFloat = (float) smallDouble; float bigFloat = (float) bigDouble; // Ausgabe der expliziten Typumwandlung von oben System.out.println("kleiner Double " + smallDouble + " wird zu "+ smallFloat ); System.out.println("großer Double " + bigDouble + " wird zu" + bigFloat );
Wie könnte hier die Ausgabe lauten?
Type-Casting mit komplexen Datentyen
Auch bei komplexen Datentypen ist ein Type-Cast möglich. Da wir Klassen und Objekte erst später behandeln, wollen wir hier nur kurz darauf eingehen.
Damit eine Typumwandlung zwischen Objekten verschiedener Klassen möglich ist, muss zwischen den Klassen eine Vererbungsbeziehung bestehen. Objekte gehören nicht nur ihrer eigenen Klasse, sondern automatisch auch den Oberklassen an, von denen geerbt wurde, also kann man hier auch ohne den cast-Operator implizit umwandeln. Da alle Objekte von der Klasse java.lang.object abgleitet sind, kann somit auch jedes Objekt in den Datentyp Object umgewandelt werden.
Der umgekehrte Weg, also in den Datentyp einer Kindklasse umzuwandeln, funktioniert jedoch nicht immer problemlos ohne Überprüfung.
Beispiel 5:
// lokale Variablen String arr1= "123456"; /* implizite Typumwandlung von dem Datentyp String in den Datentyp Object */ Object ref1= arr1; /* explizite Typumwandlung von dem Datentyp Object in den Datentyp String als Array */ String []arr2 = (String[]) ref1; System.out.println("Zeichenkette arr1:" + arr1+ " wird zu " + arr2);
Wie könnte hier die Ausgabe lauten?
Die oben aufgezeigten Beispiele sollen demonstrieren, dass man nicht „blind“ den cast-Operator verwenden sollte. Dies kann zu Ungenauigkeiten und wie im letzten Beispiel sogar zu Programmabstürzen mit einer java.lang.ClassCastException führen. Exceptions werden in einem späteren Kapitel behandelt.