1.11 Variablen 2: Scope & Casting

Einführung

Wir sehen uns nun noch zwei vertiefende Themen zu Variablen in Java an, die man meiner Erfahrung nach erst bewusst ausnutzt, wenn man bereits etwas Übung hat. Deswegen haben wir sie noch nicht vorher betrachtet.

Gültigkeitsbereich (Scope)

Der Gültigkeitsbereich einer Variablen legt fest, von wo aus wir auf sie zugreifen können. Anders ausgedrückt, legt er fest, wo diese Variable überhaupt existiert. Sehen wir uns direkt ein Beispiel an:

public class BeispielScope {

  public static void main(String[] args) {
    
    int ersteZahl = 1;
    
    while(ersteZahl < 100){
      int zweiteZahl = ersteZahl;
      ersteZahl = zweiteZahl + 1;		
      
      System.out.println(ersteZahl);
      System.out.println(zweiteZahl);
    }
    
    System.out.println(ersteZahl);
    System.out.println(zweiteZahl); // FEHLER!
  }

}

Was genau in dieser Schleife passiert ist hier für uns zweitrangig. Wichtig sind folgende Beobachtungen.

  • Die Variable ersteZahl wird bereits vor der Schleife deklariert. Das führt dazu, dass sie auch nach Abschluss der Schleife noch existiert.
  • Die Variable zweiteZahl wird innerhalb der Schleife deklariert. Genauer gesagt, wird sie zu Beginn jedes einzelnes Schleifendurchlaufs deklariert. Da eine Variable mit einem bestimmten Namen aber immer nur einmal existieren kann, muss ihre Gültigkeit mit Beenden des Schleifendurchlaufs beendet sein. So kann dann bei Beginn des folgenden Durchlauf eine neue Variable mit dem gleichen Namen erzeugt werden.
    Da die Existenz dieser Variablen mit Beenden des Schleifendurchlaufs endet, existiert sie auch nach dem kompletten Abschluss der Schleife nicht mehr. Das führt zu der im Programmtext markierten Fehlermeldung.

Allgemein gilt, dass eine Variable immer nur in dem Block in dem sie deklariert wird Gültigkeit hat. Ein Block ist dabei im Grunde alles, was mit geschweiften Klammern zusammengefasst wird. Dazu zählen beispielsweise Schleifen, if-Abfragen und Methoden.

Wenn wir dieses Phänomen im Hinterkopf behalten, können wir es bewusst einsetzen, zum Beispiel, wenn wir denselben Namen für eine Variable an verschiedenen Stellen gerne benutzen möchten.

Typumwandlung (Casting)

Wir wissen bereits, dass es verschiedene Datentypen für ganze Zahlen gibt. Wenn wir eine Variable eines kleinen Typs wie byte vorliegen haben, können wir ohne Probleme ihren Wert einer Variable eines größeren Typs zuweisen:

public class Casting {

    public static void main(String[] args) {
        byte byteZahl = 99;

        short shortZahl = byteZahl;
        int intZahl = byteZahl;
        long longZahl = shortZahl;

        double doubleZahl = intZahl;
        
    }

}

Es geht sogar noch mehr: Wir können ihren Wert wie in der letzten Zeile auch in einer double-Variablen ablegen.

Dass wir hier von einem Datentyp zu einem anderen wechseln, merken wir im Grunde gar nicht – die Umwandlungen von short zu int etc. laufen automatisch.

Sobald wir allerdings von einem größeren Datentyp zu einem kleineren wechseln wollen, müssen wir diese Entscheidung explizit mit dem sogenannten Cast-Operator bestätigen. Dieser besteht lediglich aus runden Klammern, in denen der gewünschte neue Datentyp steht:

public class Casting {

    public static void main(String[] args) {
        
        double doubleZahl = 99;
        int intZahl = (int) doubleZahl;
        System.out.println(intZahl); // Ausgabe: 99
        
        doubleZahl = 12.25;        
        intZahl = (int) doubleZahl;        
        System.out.println(intZahl); // Ausgabe: 12     
        
        short shortZahl = (short) intZahl;        
        System.out.println(shortZahl); // Ausgabe: 12  
        
    }

}

Lassen wir diese zusätzlichen Angaben wie (int) weg, erhalten wir eine Fehlermeldung. Das liegt daran, dass wir uns hier bewusst sein müssen, dass mit dieser Umwandlung Daten verloren gehen können. Zum Beispiel gehen bei der Umwandlung von einen double– in einen int-Wert die Nachkommastellen verloren. Dies kann zu schwer auffindbaren Fehlern führen. Andererseits können wir dies aber gelegentlich auch ausnutzen, falls eine bestimmte Rechnung dies erfordert.

Etwas überraschend ist vielleicht, dass wir auch Character-Werte in ganze Zahlen umwandeln können und umgekehrt:

public class Casting {

    public static void main(String[] args) {

        int intZahl = 99;
        char charZeichen = (char) intZahl;
        System.out.println(charZeichen); //Ausgabe: c
        
        charZeichen = 'x';
        intZahl = (int) charZeichen;
        System.out.println(intZahl); //Ausgabe: 120

    }

}

Das liegt daran, dass Character-Werte von Java intern als ganze Zahlen verwaltet werden.

Das explizite Casten wird uns später in der objektorientierten Programmierung noch einmal begegnen. Dort werden wir auch sehen, wie man einen String in einen Zahlenwert umwandeln kann.