14 Typ-Casting
14.1 Implizites Casten
 
Elementare Typenver-
größerung
Wir betrachten zunächst ein sehr einfaches Programm. Es sollen die Zahlen 8 und 3 dividiert werden. Dazu deklarieren wir die beiden Zahlen als int-Werte. Den Quotienten legen wir ebenfalls in einer als int deklarierten Variablen ab.
 
Download:
TypeCast1.java
public class TypeCast1 {



  public static void main (String[] args) {

      int a = 8;

      int b = 3;

      int q = a/b;

      System.out.println(a+"/"+b+"="+q);

  }

}
Ausgabe 8/3=2
 
  Dass der ermittelte Wert nicht korrekt sein kann, verwundert nicht. Vielleicht hat man mit einem gerundeten Ergebnis gerechtet. Stattdessen sieht es aus, als seien alle Nachkommastellen abgeschnitten. Der Operator '/' führt in unserem Beispiel eine sog. Ganzzahldivision durch. Verändern wir das Programm etwas:
 
Download:
TypeCast2.java
public class TypeCast2 {



  public static void main (String[] args) {

    int a = 8;

    int b = 3;

    float q = a/b;

    System.out.println(a+"/"+b+"="+q);

  }

}
Ausgabe 8/3=2.0
 
  Offensichtlich wird wieder eine Ganzzahldivision durchgeführt. Das Ergebnis also ein int-Wert wird aber in einer float-Zahl abgelegt. Es wird automatisch eine Typenumwandlung vorgenommen. Wir sprechen lieber von einem impliziten Cast. Dass dabei Informationen verloren gehen, liegt hier nicht am Casten sondern an der Ganzzahldivision. Tatsächlich lässt Java implizites Casten zu, wenn keine Informationen verloren gehen.
Die folgende Variante erlaubt es das Ergebnis als Fließkommazahl zu berechnen:
 
Download:
TypeCast3.java
public class TypeCast3 {



  public static void main (String[] args) {

    float a = 8;

    float b = 3;

    float q = a/b;

    System.out.println(a+"/"+b+"="+q);

  }

}
Ausgabe 8.0/3.0=2.6666667
 
  Der Operator führt in diesem Beispiel eine Fließkommazahl-Division aus. Wir erkennen, dass die Funktionalität des Divisionsoperator mehrdeutig erscheint. Es kann sich wie im letzten Beispiel um um eine Ganzzahl-Division oder wie im Beispiel davor um eine Fließkommazahl-Division handeln. Wir sagen der Operator ist überladen1). Dass es trotzdem zu  keinen Konflikten kommt, liegt daran, dass der Kompiler den Operator kontextabhängig übersetzt, d.h. die Funktionalität des Operators hängt davon ab, in welcher 'Umgebung er steht'. Die Genauigkeit des Ergebnisses der Division lässt sich übrigens weiter erhöhen, wenn man statt des Typs float den Typ double wählt. Allerdings ist die Lösung unseres Problems nicht befriedigend. Was kann man nämlich tun, um das gleiche Ergebnis zu bekommen, ohne die Typen von Dividend und Divisor zu verändern. In 14.2 werden wir eine befriedigende Lösung zeigen.

Halten wir fest: Wir haben im Beispiel
TypeCast2.java einen Cast von int nach float vorgenommen. Geht er auch in umgekehrter Richtung?
 
 
public class TypeCast4 {



  public static void main (String[] args) {

    float a = 8;

    float b = 3;

    int q = a/b;

    System.out.println(a+"/"+b+"="+q);

  }

}
  Der Versuch scheitert, der Kompiler verweigert die Übersetzung.
Es stellt sich also die Frage, wann ist implizites Casten möglich? Die Antwort ist einfach. Sie ist implizit möglich, wenn keine Informationen verloren gehen können.
 
byte nach short, int, long, float und double
short nach int, long, float und double
int nach long, float und double
long nach float und double
float nach double
 
Da sich hinter einem char nichts anders als eine short-Zahl verbirgt, die lediglich als ASCII-Kode interpretiert wird, lässt sich ein char in die gleichen Typen implizit casten wie auch der Typ short.
 
char nach int, long, float und double
 
  Betrachten wir ein weiteres Beispiel impliziter Typenumwandlung.
 
Das Pluszeichen ist überladen. Wir betrachten die folgende Java-Programmsequenz:

int a = 2;
int b = 3;
System.out.println("Die Summe ist: "+ a+b);
System.out.println("Die Summe ist: "+ (a+b));

Die Ausgaben, die die beiden letzten Zeilen verursachen, lauten

Die Summe ist: 23
Die Summe ist: 5

Was geschieht? Die Methode println erzeugt ein String-Objekt, das auf dem Bildschirm ausgegeben wird. Was steht in diesem String-Objekt? Zunächst die Zeichenkette, die zwischen den Anführungsstrichen "... " steht. Das Pluszeichen, das in unserem Fall dieser Zeichenkette folgt, zeigt an, dass eine weitere Zeichenkette angehängt (= konkateniert) werden soll. Es folgt aber der Bezeichner "a" , der für eine Variable vom Typ int steht. Was nun geschieht, ist sehr raffiniert. Der Zahlenwert, der in "a" gespeichert ist, wird implizit zu einer Zeichenkette umgewandelt und der Zeichenkette "Die Summe ist: "  hinzugefügt. In dem von println erzeugten String steht jetzt also "Die Summe ist: 2".  Der Vorgang wiederholt sich mit dem zweiten Pluszeichen und wir erhalten schließlich: Die Summe ist: 23. Sehr schön erkennt man auch, dass Java den Ausdruck in den Klammern von println von links nach rechts auswertet. 
Die Reihenfolge der Auswertung kann man mit zusätzlichen Klammern beeinflussen, wie die zweite Ausgabe zeigt. Vor der ersten Konkatenation muss das Pluszeichen zwischen "
a" und "b" in der Klammer ausgewertet werden. Da es sich bei "a" und "b" beides mal um Bezeichner für int-Variablen handelt, wird das Pluszeichen als Additionszeichen interpretiert und die Klammer dementsprechend zu 5 ausgewertet, bevor ihr Wert wieder als String der Zeichenkette "Die Summe ist: " zu "Die Summe ist: 5" konkateniert wird. Wie schon beim '/'-Operator sehen wir, dass auch der '+'- Operators überladen ist.

Man könnte jetzt geneigt sein, folgendes zu versuchen:

int x = 2;
String a = x;

und hoffen, dass bei der Zuweisung a = x der Inhalt bei Ablegen in a eine implizite Typenumwandlung, von einer int - Zahl zu einem String erfährt. Tatsächlich übersetzt der Javacompiler die letzte Zeile nicht und meldet einen Fehler. Man könnte die letzte Zeile durch

String a = ""+x;

casten ersetzten, um das gewünschte zu erreichen. Das Pluszeichen konkateniert den Leerstring mit dem zu einem String gewandelten Inhalt von x. Um Missverständnisse zu vermeiden, betonen wir, dass der Inhalt von x unverändert eine int-Zahl bleibt. Das ist auch der Grund, warum wir den Begriff des Castens dem der Typenumwandlung vorziehen.
Fußnoten  

1)

Kinder suchen beim sog. Teekesselspiel nach diesen überladenen Begriffen: z.B. Bank. Vom Kontext hängt es ab, ob man eine Institution meint, bei der man ein Kontoführen kann oder ob eine Sitzgelegenheit gemeint ist, die z.B. in einem Park steht. Somit könnten wir sagen, dass der Begriff 'Bank' überladen ist. [zurück]
 
zu 14.2 Explizites Casten
zur Startseite www.pohlig.de  (C) MPohlig 2005