Casting

Mit Casting bezeichnet man in der Programmierung die Umwandlung des Wertes einer Variable in einen anderen Typ.

implizites Casting

Implizites Casting geschieht immer dann, wenn man einer Variablen einen Wert zuweist, der nicht dem der Variablen entspricht.


    int i = 15;
    double d = i;

Die interne bitweise Darstellung der Zahl 15 als Dezimalzahl und als Gleitkommazahl sind sicherlich verschieden, da eine Gleitkommazahl aus Mantisse und Exponent besteht (in diesem Fall 0.15e+2, und das dann noch binär). Deshalb muss die Zahl umgerechnet werden. Die Umrechnung geschieht in diesem Fall automatisch. Bei den primitiven Datentypen erfolgt implizites Casting in dieser Richtung:


    byte -> short -> int -> long -> float -> double

d.h. wenn der Zieltyp "grösser" ist als der aktuelle Wert und deshalb keine Informationen durch Rundung verloren gehen. Wenn man versucht einen Wert einer Variablen mit "kleinerem" Typ zuzuordnen, erfolgt eine Fehlermeldung vom Compiler. Bei einer solchen Operation muss das Casting explizit erfolgen.


    Tutor04.java:20: possible loss of precision
    found   : double
    required: int
        i = d;
            ^
    1 error

Na wenn dass nicht mal eine exakte und verständliche Fehlermeldung ist, grosses Kompliment an die Entwickler der Java-Compilers.

explizites Casting

Explizites Casting erfolgt durch die Angabe des Zieltyps in Klammern vor dem Ausdruck.


    i = (int) d;

Explizites Casting muss immer dann erfolgen, wenn bei der Typumwandlung Informationen verloren gehen können, z.B. bei einer solchen Zuweisung:


    i = (int) 10.8;   // dies ergibt 10
    i = (int) -10.8;  // dies ergibt -10

Beim Casting auf ganze Zahlen werden die Nachkommastellen abgeschnitten, d.h. es wird immer zur Null hin gerundet.

Natürlich darf man auch explizit casten, wo es eigentlich nicht nötig ist.


    d = (double) i;
    i = (int) 15;

Casting von Objekten

Bei Objekten funktioniert das genauso. Auf Vererbung wird in LektionB3 eingegangen. Die Umwandlung des Typs eines Objektes in eine Superklasse kann implizit erfolgen. Umkegehrt muss der Typ angegeben werden. Sei folgende Klassenhirarchie gegeben:


  class A {
    public void foo(A a) { ... }
    ...
  }

  class B extends A { ... }

  class C extends A { ... }

Alle Objekte vom Typ B und C können implizit in den Typ A gecastet werden.


    B b = new B();
    C c = new C();
    A a = b;        // implizites Casting von b nach A
    a.foo(c);       // implizites Casting von c nach A

Um eine (zuvor "runtergecastete") Variable in einen "höheren" Typ umzuwandeln muss explizit gecastet werden.


    b = (B) a;
    c = (C) a;      // throws ClassCastException

Da das Objekt a eigentlich vom Typ B ist, kann es auch in diesen Typ gecastet werden. Mit dem Typ C funktioniert das nicht. Der Compiler kann so etwas nicht bemerken. Solche Fehler werden zur Laufzeit mit einer ClassCastException bestraft. Damit man sich mit der Exception nich herumschlagen muss, gibt es in Java einen Operator, der prüft, ob sich ein Objekt in einen bestimmten Typ umwandeln lässt (das funktioniert genau für die Klassen, die oberhalb des Objektes im Hierarchiebaum liegen).


    System.out.println(a instanceof B);  // ergibt true
    System.out.println(a instanceof C);  // ergibt false

Eine übliche Abfrage sieht so aus:


    if (a instanceof B) {
      b = (B) a;
    } else {
      b = null;
      System.out.println("Typumwandlung nicht möglich");
    }

Wer das Beispiel mit den Klassen nicht versteht, dazu wird es auch noch eine Lektion geben. Gleiches gilt für Exceptions.


Erstellt von Markus Durzinsky, aktualisiert 2004-03-17
Für Fragen, Probleme oder Anregungen stehe ich gerne zur Verfügung