Java-Variablen
Variablen in Java deklarieren und initialisieren, Variablentypen verstehen (lokal, Instanz, statisch) und Java-Namenskonventionen anwenden.
Eine Variable ist ein benannter Speicherort mit einem festen Typ. Nach der Deklaration kann sich der Typ nicht ändern, aber der enthaltene Wert kann es in der Regel. Der Typ bestimmt, wie viel Speicher die Variable belegt, welche Werte zulässig sind und welche Operationen der Compiler erlaubt. Dieses Kapitel erklärt, wie man Variablen deklariert, wie man sie initialisiert, die vier Arten, die Java unterscheidet, und die Regeln rund um final, var und Sichtbarkeitsbereiche.
Eine Variable deklarieren
Die Grundform besteht aus einem Typ, gefolgt von einem Namen und einem Semikolon:
type name;Zum Beispiel reserviert int score; einen int-großen Slot mit dem Namen score. Der Typ ist einer der eingebauten Java-Typen (int, double, boolean, char, …) oder eine beliebige Klasse oder Schnittstelle — die vollständige Liste findet sich unter Java Data Types.
Die einfachsten Deklarationen:
int score;
String name;
boolean ready;Diese reservieren Speicher; sie legen aber noch keinen Wert darin ab.
Initialisieren
Um einen Wert zuzuweisen, verwendet man =:
int score = 0;
String name = "Ada";
boolean ready = true;Man kann auch deklarieren und zuweisen getrennt voneinander:
int score;
score = 0;Oder mehrere Variablen desselben Typs auf einmal deklarieren:
int x = 1, y = 2, z = 3;(Eine Variable pro Zeile ist meistens übersichtlicher.)
Lokale Variablen müssen vor der Verwendung zugewiesen werden
Eine lokale Variable — innerhalb einer Methode deklariert — hat keinen Standardwert. Der Compiler verweigert das Lesen, bis ein Wert zugewiesen wurde:
public static void main(String[] args) {
int x;
// System.out.println(x); // compile error: variable x might not have been initialized
x = 5;
System.out.println(x); // OK
}Das ist eines der nützlichsten Sicherheitsmerkmale von Java — es fängt eine Klasse von Fehlern ab, die andere Sprachen durchschlüpfen lassen.
Die vier Arten von Variablen
Java unterscheidet vier Variablenkategorien danach, wo sie deklariert werden:
- Lokale Variablen — innerhalb einer Methode oder eines Blocks deklariert. Existieren nur, solange die Methode läuft. Kein Standardwert. Müssen vor der Verwendung initialisiert werden.
- Instanzvariablen (Felder) — innerhalb einer Klasse, aber außerhalb jeder Methode deklariert. Eine Kopie pro Objekt. Standardwert ist
0/0.0/false/null. - Statische Variablen (Klassenvariablen) — mit dem Schlüsselwort
staticdeklariert. Eine gemeinsame Kopie für alle Instanzen der Klasse. Standardwert ist0/false/null. - Parameter — in einer Methodensignatur deklariert; erhalten den vom Aufrufer übergebenen Wert.
public class Counter {
static int totalCounters; // static (class) variable
int count; // instance variable
public void add(int delta) { // delta is a parameter
int doubled = delta * 2; // doubled is a local variable
count += doubled;
}
}Instanz- und statische Variablen begegnen einem erneut in den OOP-Kapiteln; vorerst werden die meisten selbst geschriebenen Variablen lokal sein.
final — einmalige Zuweisung
Das Voranstellen von final vor eine Deklaration macht die Variable zu einer einmaligen Bindung. Nach der ersten Zuweisung kann sie nicht mehr geändert werden:
final int MAX_RETRIES = 3;
// MAX_RETRIES = 4; // compile error: cannot assign a value to final variableDie Verwendung von final für Dinge, die sich nicht ändern sollen, macht die Absicht explizit und lässt den Compiler versehentliche Neuzuweisungen abfangen. Per Konvention werden final-Felder, die feste Konstanten enthalten, in UPPER_SNAKE_CASE benannt (siehe Java Naming Conventions).
Zu beachten ist, dass final die Bindung einfriert, nicht das Objekt, auf das sie zeigt. Eine final-Referenz kann nicht neu zugewiesen werden, aber das Objekt, auf das sie verweist, kann noch verändert werden:
final int[] nums = {1, 2, 3};
nums[0] = 99; // OK — the array contents change
// nums = new int[5]; // compile error — the reference is finalvar — den Compiler den Typ bestimmen lassen
Seit Java 10 kann man var anstelle eines Typs für lokale Variablen schreiben, wenn die rechte Seite den Typ offensichtlich macht:
var name = "Ada"; // inferred as String
var score = 0; // inferred as int
var values = new int[10]; // inferred as int[]var ist keine dynamische Typisierung — die Variable hat weiterhin einen festen Typ, der Compiler leitet ihn nur ab. Einschränkungen:
- Nur für lokale Variablen.
- Die rechte Seite muss vorhanden sein (
var x;ist unzulässig). - Nicht erlaubt für Parameter, Instanzvariablen oder statische Variablen.
var ist am nützlichsten, wenn der Typname lang oder aus dem Kontext offensichtlich ist:
var orders = new HashMap<String, List<Order>>();Bei nicht offensichtlichen abgeleiteten Typen sollte man gewöhnliche Typdeklarationen verwenden.
Sichtbarkeitsbereich (Scope)
Eine Variable ist in ihrem Sichtbarkeitsbereich — sichtbar — von ihrer Deklaration bis zum Ende des umgebenden Blocks:
public static void main(String[] args) {
int outer = 1;
if (outer > 0) {
int inner = 2;
System.out.println(outer + inner); // both visible
}
// System.out.println(inner); // compile error: inner is out of scope
}Es ist nicht möglich, zwei lokale Variablen mit demselben Namen in überlappenden Sichtbarkeitsbereichen zu deklarieren — aber ein Name kann in zwei getrennten, nicht überlappenden Blöcken wiederverwendet werden:
for (int i = 0; i < 3; i++) { /* i lives here */ }
for (int i = 0; i < 5; i++) { /* a new, separate i */ } // fineKleine Sichtbarkeitsbereiche für Variablen sind gute Praxis: Jede Variable sollte so nah wie möglich an der Stelle deklariert werden, an der sie erstmals verwendet wird.
Ein funktionierendes Beispiel
Was kommt als Nächstes
Java Naming Conventions behandelt die Standardregeln, die jede Java-Codebasis für Klassen-, Methoden-, Variablen- und Konstantennamen befolgt.