» Tutorial / Java Grundlagen / Variablen

Der nächste Schritt in Richtung Java vollzieht sich zusammen mit dem vorhergehenden Kapitel. Hier werden wir besprechen, was Variablen sind, wozu sie benötigt werden und noch einige weitere Details im Umgang mit ihnen.

Eine Variable ist eine benannte Speicherstelle, an der Daten in Form von Zahlen oder Zeichen gespeichert werden können. Eine Variable ist zudem strinkt typisiert und wird über ihren Datentyp exakt spezifiziert.


» Klassifikation nach oben «

In Java gibt es durchaus mehrere Typen von Variablen, wobei wir diese hier kurz diskutieren möchten. Wir unterscheiden insgesamt fünf Arten von Variablen.


» lokale Variablen

Alle innerhalb eines Blocks oder einer Methode definierten Variablen mit einem begrenzten Gültigkeitsbereich werden als lokale Variablen bezeichnet. Sie werden statisch angelegt und bedürfen keiner dynamischen Allokation.

» konstante Variablen

Wird eine Variable als konstant deklariert, so kann sie ihren ihr einmal zugewiesenen Wert fortan nicht mehr ändern. Das Speicherverhalten ist analog zu den lokalen Variablen.

» statische Variablen

Statische Variablen haben die selben Auszeichnungen wie lokale Variablen, unterscheiden sich aber grundlegend in ihrem Gültigkeitsbereich und im Speicherverhalten. Des weiteren können sie auch als konstant markiert werden.

» Klassenvariablen

Alle benutzerdefinierten Variablen, welche jedoch nicht direkt erzeugt werden oder an eine Instanz gebunden sind.

» Instanzvariablen

Alle von einer Klasse instanziierten und an ein Objekt gebundendenen Variablen.


» Deklaration einer Variable nach oben «

Bei der Deklaration wird eine Variable erzeugt, welche gleichzeitig durch ihren Datentyp spezifiziert wird.

Syntaktisch wird zunächst der Datentyp einem Variablenbezeichner vorangestellt, durch den die Variable fortan verwendet und angesprochen werden kann. Die Anweisung endet wie gewohnt durch ein Semikolon.


Typ Name;
    

Das folgende Beispiel deklariert eine Intergervariable.


public class MyClass
{
  public static void main(String[] args)
  {
    int i;  
  }
}
    

» Initialisierung nach oben «

Im folgenden schließt sich gewöhnlich die Initialisierung, sprich Wertezuweisung an. Hierbei werden den Variablen Daten zugewiesen. Ansonsten sind alle Variablen mit einem Standardwert vorbelegt. Dieser hängt wiederum vom Datentyp ab und kann aus dem vorhergehenden Kapitel ermittelt werden.

Die Initialisierung erfolgt durch den Zuweisungsoperator in Form eines Gleichheitszeichens. Es sei allerdings darauf hingewiesen, dass man nur zum Datentyp passende Werte verwendet, da man sonst Fehler erhält.


Name = Wert;
    

Das folgende Beispiel deklariert eine Intergervariable und initialisiert sie in der nächsten Anweisung mit einem Wert.


public class MyClass
{
  public static void main(String[] args)
  {
    int i;
    i = 2;  
  }
}
    

Interessanterweise lassen sich die Schritte der Deklaration und Initialisierung in einer einzigen Anweisung zusammenfassen.


Typ Name = Wert;
    

Ein praktisches Beispiel für die kombinierten Anweisungen.


public class MyClass
{
  public static void main(String[] args)
  {
    int i = 2;  
  }
}
    

» Zuweisung von Werten nach oben «

Auch nachträglich können fast alle Arten von Variablen noch verändert werden. Hierbei kann man noch einmal Initialisierung und Zuweisung unterscheiden, obwohl sie an sich gesehen beide das Gleiche meinen. Um Klarheit zu verschaffen bezeichnet man lediglich die Erstzuweisung eines Wertes an eine Variable als Initialisierung. Alle weiteren als reine Zuweisung.


Name = Wert;
    

Ein praktisches Beispiel für die nachträgliche Zuweisung eines Wertes an eine Variable.


public class MyClass
{
  public static void main(String[] args)
  {
    int i = 2;
        i = 5; 
  }
}
    

» Konstanten nach oben «

Konstante Variablen bilden eine Sonderstellung. Bei ihrer Deklaration muss sich noch in der selben Anweisung die Initialisierung anschließen, da Konstanten später nicht mehr verändert werden können.

Bei der Deklaration wird das Final - Schlüsselwort verwendet, welches die Variable als Konstante markiert.


final Typ Name = Wert;
    

Ein praktisches Beispiel für die Deklaration einer konstanten Variable. Beachten Sie die Voranstellung des Final - Schlüsselwortes vor den eigentlichen Typ.


public class MyClass
{
  public static void main(String[] args)
  {
    final int i = 2;       
  }
}
    

» statische Variablen nach oben «

Statische Variablen sind im Gegensatz zu anderen Variablen einer Klasse nicht an eine von ihr gebildeten Instanz gebunden. Das heißt, dass statische Variablen immer zur Klassendefinition selbst gehören und nicht mit einer neuen Instanz erstellt werden. Statische Variablen gelten also für alle Instanzen einer Klassendefinition.

Bei der Deklaration wird das Static - Schlüsselwort verwendet, welches die Variable als statisch markiert.


static Typ Name;
    

Ein praktisches Beispiel für die Deklaration einer statischen Variable. Beachten Sie die Voranstellung des Static - Schlüsselwortes vor den eigentlichen Typ. Das Public - Schlüsselwort muss uns an dieser Stelle noch nicht interessieren.


class Test
{  
  static public int i = 2;       
}
    

Da aber statische Variablen nun nicht mehr zu einer einzelnen Instanz zählen, sondern zur Klasse, werden sie auch nur ein einziges mal erzeugt. Auch der Zugriff unterscheidet sich. Eine solche Variable kann nur über den Klassennamen erreicht werden. Dazu wird der Variablenname nach der direkten Klasse durch einen Punkt getrennt. Des weiteren befindet sich unsere Testvariable in einer externen Klasse innerhalb derselben Datei.


class Test
{  
  static public int i = 2;       
}

public class MyClass
{
  public static void main(String[] args)
  {
    System.out.print(Test.i);      
  }
}
    

2
    

Die Merkmale von konstanten und statischen Variablen lassen sich auch vereinen. Dazu müssen lediglich beide Schlüsselwörter verwendet werden. Die Initialisierung ist in diesem Fall dann wieder unabdingbar.


final static Typ Name;
    

Zu Demonstrationszwecken bedienen wir uns der vorhergehenden Beispiele. Wir haben lediglich die beiden Schlüsselwörter Final und Static vereint, und somit auch ihre Besonderheiten in Form einer expliziten Initialisierung und der Aufrufregeln.


class Test
{  
  final static public int i = 2;       
}

public class MyClass
{
  public static void main(String[] args)
  {
    System.out.print(Test.i);      
  }
}
    

2
    

» Gültigkeitsbereich nach oben «

Alle erzeugten Variablen unterliegen einem sogenannten Gültigkeitsbereich. Dieser bestimmt, in Abhängigkeit des Ortes der Variablendeklaration, deren Sichtbarkeit und Lebensdauer.

Mit Ausnahme der statischen Variablen, sind alle anderen immer auf ihren Block beschränkt. Endet ein Block in Form eines Funktionsrumpfes, zweier Blockklammern oder einer Klassendefinition, so endet auch die Speicherberechtigung einer Variable innerhalb dieses Blocks.

Eine einmal deklarierte Variable ist nur in ihrem und weiteren Unterblöcken sichtbar. Wird der Block verlassen, so wird die Variable ebenfalls gelöscht.

Unser nächstes Beispiel definiert eine Zeichenvariable. Danach bilden wir einen neuen Block in Form einer Bedingung. Innerhalb dieses Blocks wird eine neue Variable deklariert. Dort könenn wir noch auf die untergeordnete lokale Variable zugreifen. Auf die neue Variable hingegen nicht mehr, da mit Verlassen des Blocks auch diese Variable gelöscht wird.


public class MyClass
{
  public static void main(String[] args)
  {
    int i = 2;
		 
    if(true)
    {
      char c = '!';
      
      System.out.println(i);
      System.out.println(c);
    }		
		
      System.out.println(i);
    //System.out.println(c);  // nicht mehr sichtbar
  }
}
    

2
!
2
    

Wie bereits erwähnt, so liegt der Unterschied bei den statischen Variablen. Sie haben im Rahmen ihrer Klasse einen globalen Gültigkeitsbereich und stehen allen Teilen des Programms zur freien Verfügung. Sie terminieren erst bei Programmende aus dem Speicher.


» Inkrementierung und Dekrementierung nach oben «

An dieser Stelle möchten wir einen kleinen Auszug aus dem Kapitel der Operatoren einschieben. Oft kommt es in der angewandten Programmierung zu dem Fall, dass eine Variable um jeweils nur einen Zählerstand erhöht oder erniedrigt wird. Aus diesem Grund stehen zwei Operatoren zur Verfügung, die auf schnelle Weise exakt diese Anforderung realisieren.

Beide Operatoren bestehen entweder aus einem doppelten Plus- oder Minuszeichen. Das Pluszeichen inkrementiert und das Minuszeichen dekrementiert eine Variable.


++Variable;
Variable++;
--Variable;
Variable--;
    

Das folgende Beispiel wird die zwei Variablen jeweils um einen Stellenwert erhöhen, beziehungsweise erniedrigen.


public class MyClass
{
  public static void main(String[] args)
  {
    int i = 2;
    int d = 2;	    	
		
    System.out.println(++i);
    System.out.println(--d);
  }
}
    

3
1
    

In unserem Beispiel haben wir die Operatoren den Variablen vorangestellt. Nun gibt es auch einen Fall, in dem wir die Operatoren den Variablen nachstellen können, wobei die Begriffe des Präfix und Postfix ins Spiel kommen.


» Präfix

Bei Operationen mit einem Präfix wird als erstes die Variable hoch- beziehungsweise heruntergezählt und dann eine etwaige weitere Operation in Form einer Zuweisung durchgeführt.

» Postfix

Bei Operationen mit einem Postfix werden als erstes alle weiteren Operationen durchgeführt. Erst danach wird dann die entsprechende Variable hoch- beziehunghsweise heruntergezählt.

So simpel sich das System auch anhören mag, so entscheident kann es auch den Programmfluß beeinflussen. Das folgende Beispiel soll dieses Vorgehen verdeutlichen. Man bedenke jedoch, dass sich die vorliegende Technik nur dann auswirkt, wenn sich mehrere Operationen in einer Anweisung befinden.

Folglich werden wir ein Beispiel einführen, welchen die unterschiedlichen Ergebnisse der Inkrementierung beziehungsweise Dekrementierung in einer multiplen Anweisung darstellt.


public class MyClass
{
  public static void main(String[] args)
  {
    int a = 2;
    int b = 2;	    	
		
    System.out.println(++a);
    System.out.println(a++);
    System.out.println(a  );
    System.out.println(--b);
    System.out.println(b--);
    System.out.println(b  );
  }
}
    

3
3
4
1
1
0
    

» Konvertierung nach oben «

Wie bereits im letzten Kapitel angekündigt, so wollen wir hier noch einmal das Thema der Konvertierung aufgreifen. Dabei konzentrieren wir uns auf die explizite Konvertierung, welche in unterschiedlichen Situationen erforderlich sein kann. Der Vollständigkeit halber können Sie hier noch einmal die hierarchische Anordnung der verschiedenen Datentypen einsehen.

Hierarchie der Standardkonvertierung

Die explizite Konvertierung erfolgt durch das Voranstellen des entsprechenden Operators samt Angabe des Zieldatentyps. Der folgende Ausdruck wird dann entsprechend dem neuen Datentyp ausgewertet.


(Typ) Variable;
    

Das folgende Beispiel demonstriert die explizite Konvertierung einer Ganzzahl in einen Zeichentyp. Zu beachten ist die entsprechende Verwendung des Konvertierungsoperators.


public class MyClass
{
  public static void main(String[] args)
  {
     int i =      33;  System.out.println(i);		
    char c = (char)i;  System.out.println(c);
  }
}
    

33
!
    

Entsprechende Fälle werden uns und auch später noch beschäftigen, wenn es darum geht, wie die Java - Standard - Bibliothek und die gesamte Vererbungshierarchie aufgebaut ist.


» Speicherverbrauch nach oben «

Alle hier vorgestellten Datentypen haben verschiedene Aspekte gemeinsam. Einmal werden sie alle auf einem lokalen Stack - Speicher konstruirt und bedürfen somit keiner dynamischen Allokation, und einmal haben sie alle feste Bytegrößen.

Im folgenden finden Sie eine Übersicht über die exakten Bytes pro Datentyp.

entsprechende Datentypen
 
boolean, byte
short, char
int, float
long, double

Eine weitere Betrachtung kommt den benutzerdefinierten Datentypen in Form der Klassen zu. Hier verhalten sich die oben angesprochenen Konzepte ganz anders.

Zunächst werden alle Klasseninstanzen dynamisch auf dem Arbeitsspeicher angelegt und belasten somit nicht den Stack. Außerdem errechnet sich die Bytegröße einer Instanz aus der Summe aller in ihr definierten Variablen.


» Arrays und Strings nach oben «

In Java werden auch Arrays und Strings als Datentypen angesehen. Diese unterliegen jedoch diversen Vorzügen. So wurden beide als Klassen implementiert und stellen darüber hinaus viele interessante Möglichkeiten der Verwaltung und Manipulation ihrer Daten zur Verfügung.

Leider bedürfen sie einer gesonderten Behandlung in eigenen Kapiteln, da sie unter anderem vom Speichermanagement und dem syntaktischen Einsatz abweichen. Aus diesem Grund finden Sie in den folgenden Kapiteln detaillierteste Informationen.


« Kapitel Kapitelübersicht nach oben Kapitel »