Casting 💱

(auch: Typumwandlung)

Beim Casting wird ein Wert eines bestimmten Datentyps in einen anderen Datentyp umgewandelt

… bei primitiven Datentypen

Implizite Typumwandlung (upcasting)

Bei der impliziten Typumwandlung wird ein “niederwertiger” Typ einem “höherwertigen” Typ zugewiesen (die Umwandlung geschieht automatisch, oder eben “implizit”):

int i = 2;
double d = i;

upcast

Grafik: #, Quelle: java-tutorial.org

Explizite Typumwandlung (downcasting)

Bei der expliziten Typumwandlung wird ein “höherwertiger” Typ in “niederwertigen” Typ umgewandelt. Dies geschieht mittels cast-Operators. Der cast-Operator setzt sich aus dem Ziel-Typ in runden Klammern zusammen:

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

downcast

Grafik: #, Quelle: java-tutorial.org

… bei komplexen Datentypen

💬 engl.: Reference Casting

⚠️ Achtung! Der folgende Abschnitt ist erst relevant, wenn du bereits mit Vererbung und Klassenhierarchien vertraut bist!

Beim Casting von komplexen Datentypen gibt es ebenfalls implizite und explizite Umwandlung - genau wie bei den primitiven Datentypen.

Implizite Typumwandlung (upcasting)

🔗 Siehe Polymorphie

Die implizite Typumwandlung bei komplexen Datentypen ist eine Umwandlung von einer Subklasse (Spezialisierung oder Erweiterung) zu einer ihrer Superklassen (Abstraktion der Subklasse). Es wird hierbei nicht wirklich der Datentyp des Objektes umgewandelt, sondern lediglich ein Bezeichner mit einem “niederwertigen” Datentyp verwendet:

SpecialUser specialUser = new SpecialUser();
User user = specialUser; // implizite Typumwandlung (Polymorphie)

⚠️ Da im obigen Beispiel die Variable user den Datentyp User besitzt, kann diese Referenz auf das Objekt (das ja eigentlich vom Typ SpecialUser ist) ausschließlich auf die Eigenschaften der Klasse User zurückgreifen. Alle Erweiterungen, die in SpecialUser definiert sind, sind durch die Verwendung des niederen Typs nicht zugänglich!

👩‍🏫 Falls die Klasse SpecialUser eine Methode der Klasse User überschreibt (Overriding) und diese Methode über einen Bezeichner mit Typ User aufgerufen wird, wird trotzdem die Methode aus SpecialUser aufgerufen!

Explizite Typumwandlung (downcasting)

Die Umwandlung von Superklassen zu Subklassen muss explizit geschehen (ausgehend vom obigen Beispiel):

SpecialUser specialUser = (SpecialUser) user;

Oder, wenn nur einmalig eine Methode des höherwertigen Typs (Subklasse) genutzt werden soll:

((SpecialUser) user).specialUserMethod("I need this method once!");

Natürlich geschieht das Downcasting bei komplexen Typen “auf eigene Gefahr”: Man sollte sich sehr sicher sein, dass das Objekt wirklich vom höheren Typ ist! Dafür kann der instanceof-Operator nützlich sein:

if (user instanceof SpecialUser){
    ((SpecialUser) user).specialUserMethod("I need this method once!");
}

👨‍🏫 Im Falle einer ungültigen Typumwandlung wirft der betreffende Code eine ClassCastException.