Zum Inhalt springen
Java Anfänger 25 min

Variablen in Java

Lerne alles über Variablen in Java: Deklaration, Initialisierung, Scope, finale Variablen und den Unterschied zwischen primitiven und Referenztypen.

Aktualisiert:

Variablen in Java

Variablen sind das Fundament jedes Programms. Sie sind wie beschriftete Boxen, in denen du Daten speichern, veraendern und wieder abrufen kannst. In Java gibt es dabei ein paar Besonderheiten, die du kennen solltest.

Variablen deklarieren und initialisieren

In Java musst du beim Erstellen einer Variable den Typ angeben:

// Deklaration (Variable anlegen)
int alter;

// Initialisierung (Wert zuweisen)
alter = 25;

// Deklaration + Initialisierung in einem Schritt
int gewicht = 75;
String name = "Max";
double groesse = 1.82;
boolean istStudent = true;

Mit var (Typinferenz seit Java 10)

Mit var erkennt Java den Typ automatisch:

var alter = 25;          // int
var name = "Max";        // String
var groesse = 1.82;      // double
var istStudent = true;   // boolean
var liste = List.of(1, 2, 3); // List<Integer>

Wichtig: var funktioniert nur bei lokalen Variablen (innerhalb von Methoden) und nur, wenn du sofort einen Wert zuweist.

// GEHT:
var x = 42;

// GEHT NICHT:
var y;        // Fehler! Kein Wert zugewiesen
y = 42;

Vergleich mit Python

# Python: Typ wird automatisch erkannt, kann sich aendern
name = "Max"
name = 42     # Kein Fehler! Typ aendert sich
// Java: Typ ist fest
var name = "Max";
name = 42;        // FEHLER! name ist ein String, kein int

In Java ist der Typ einer Variable unveraenderlich — einmal String, immer String.

Variablen-Typen in Java

Lokale Variablen

Lokale Variablen existieren nur innerhalb einer Methode oder eines Blocks:

public static void main(String[] args) {
    var nachricht = "Hallo";  // Lokale Variable
    System.out.println(nachricht);
} // nachricht existiert hier nicht mehr

Instanzvariablen (Felder)

Instanzvariablen gehoeren zu einem Objekt:

public class Student {
    String name;        // Instanzvariable
    int matrikelnummer;  // Instanzvariable

    public void vorstellen() {
        System.out.println("Ich bin " + name);
    }
}

Klassenvariablen (static)

Klassenvariablen gehoeren zur Klasse selbst, nicht zu einzelnen Objekten:

public class Zaehler {
    static int anzahl = 0;  // Klassenvariable

    public Zaehler() {
        anzahl++;
    }
}

Konstanten (final)

Mit final erstellst du Variablen, deren Wert sich nicht mehr aendern kann:

final double PI = 3.14159265;
final String FIRMENNAME = "MeineFirma GmbH";
final int MAX_VERSUCHE = 3;

PI = 3.0; // FEHLER! final-Variable kann nicht geaendert werden

Konvention: Konstanten werden in UPPER_SNAKE_CASE geschrieben.

public class Einstellungen {
    public static final int MAX_SPIELER = 10;
    public static final String VERSION = "2.0.1";
    public static final double MEHRWERTSTEUER = 0.19;
}

Scope (Gueltigkeitsbereich)

Der Scope bestimmt, wo eine Variable sichtbar und nutzbar ist:

public class ScopeBeispiel {
    static int klassenVariable = 100; // Ueberall in der Klasse

    public static void main(String[] args) {
        var aussen = "Ich bin aussen"; // Sichtbar in der ganzen Methode

        if (true) {
            var innen = "Ich bin innen"; // Nur im if-Block sichtbar
            System.out.println(aussen);  // OK
            System.out.println(innen);   // OK
        }

        System.out.println(aussen);      // OK
        // System.out.println(innen);    // FEHLER! innen existiert hier nicht
    }
}

Scope-Regeln

RegelErlaeuterung
Variablen sind nur in ihrem Block {} sichtbarNach der schliessenden Klammer sind sie weg
Aeussere Variablen sind in inneren Bloecken sichtbarAber nicht umgekehrt
Variablen im selben Scope duerfen nicht gleich heissenKompilierfehler!
// Shadowing: Aeussere Variable wird "verdeckt"
public static void main(String[] args) {
    var x = 10;

    if (true) {
        // var x = 20; // FEHLER in Java! Lokale Variable kann nicht verdeckt werden
        x = 20;       // OK -- gleiche Variable, neuer Wert
    }

    System.out.println(x); // 20
}

Variablen veraendern

Zuweisungsoperatoren

var punkte = 100;

punkte = 200;    // Direkte Zuweisung
punkte += 50;    // punkte = punkte + 50  --> 250
punkte -= 30;    // punkte = punkte - 30  --> 220
punkte *= 2;     // punkte = punkte * 2   --> 440
punkte /= 4;     // punkte = punkte / 4   --> 110
punkte %= 3;     // punkte = punkte % 3   --> 2

System.out.println(punkte); // 2

Inkrement und Dekrement

var zaehler = 10;

zaehler++;  // zaehler = zaehler + 1 --> 11
zaehler--;  // zaehler = zaehler - 1 --> 10

// Praefix vs. Postfix
var a = 5;
var b = a++;  // b = 5, dann a = 6 (erst zuweisen, dann erhoehen)
var c = ++a;  // a = 7, dann c = 7 (erst erhoehen, dann zuweisen)

Primitive vs. Referenztypen

Das ist einer der wichtigsten Unterschiede in Java:

Primitive Typen — Werte direkt gespeichert

int a = 42;
int b = a;     // b bekommt eine KOPIE des Werts
b = 100;       // a bleibt 42!

System.out.println(a); // 42
System.out.println(b); // 100

Referenztypen — Referenz auf ein Objekt

int[] a = {1, 2, 3};
int[] b = a;          // b zeigt auf das GLEICHE Array!
b[0] = 999;           // Aendert auch a!

System.out.println(a[0]); // 999 -- Ueberraschung!

Visualisierung

Primitive:
a: [42]      b: [42]     // Zwei getrennte Boxen

Referenz:
a: [Ref] ──┐
            ├──> [1, 2, 3]  // Beide zeigen auf dasselbe Objekt
b: [Ref] ──┘

Typkonvertierung (Casting)

Implizite Konvertierung (Widening)

Java wandelt automatisch um, wenn kein Datenverlust moeglich ist:

int ganzzahl = 42;
double dezimal = ganzzahl; // int --> double: kein Datenverlust

System.out.println(dezimal); // 42.0

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

Explizite Konvertierung (Narrowing/Casting)

Wenn Datenverlust moeglich ist, musst du explizit casten:

double dezimal = 3.99;
int ganzzahl = (int) dezimal; // Expliziter Cast

System.out.println(ganzzahl); // 3 -- Nachkommastellen abgeschnitten!

String-Konvertierung

// Zahl zu String
var zahlAlsString = String.valueOf(42);    // "42"
var zahlAlsString2 = Integer.toString(42); // "42"
var zahlAlsString3 = "" + 42;             // "42" (einfachste Variante)

// String zu Zahl
var zahl = Integer.parseInt("42");        // 42
var dezimal = Double.parseDouble("3.14"); // 3.14

Default-Werte

Instanzvariablen bekommen automatisch Default-Werte. Lokale Variablen nicht — du musst sie initialisieren:

TypDefault-Wert
int, long, short, byte0
double, float0.0
booleanfalse
char'\u0000' (Null-Zeichen)
Referenztypen (String, Arrays, etc.)null
public class DefaultWerte {
    int zahl;           // 0
    String text;        // null
    boolean aktiv;      // false

    public static void main(String[] args) {
        // var x;       // FEHLER! Lokale Variable muss initialisiert werden
        var x = 0;      // OK
    }
}

Best Practices

1. Sinnvolle Namen verwenden

// SCHLECHT:
int x = 25;
String s = "Max";
double d = 1.82;

// GUT:
int alter = 25;
String vorname = "Max";
double koerpergroesse = 1.82;

2. Variablen so spaet wie moeglich deklarieren

// SCHLECHT:
var ergebnis = 0.0;
var eingabe = "";
// ... 50 Zeilen Code ...
eingabe = scanner.nextLine();
ergebnis = berechne(eingabe);

// GUT:
// ... 50 Zeilen Code ...
var eingabe = scanner.nextLine();
var ergebnis = berechne(eingabe);

3. final nutzen, wenn der Wert sich nicht aendert

// Wenn sich der Wert nie aendert: final
final var steuerSatz = 0.19;
final var firmenName = "TechCorp";

Uebungen

Uebung 1: Variablen tauschen

Schreibe ein Programm, das die Werte zweier Variablen tauscht, ohne eine dritte Variable zu verwenden (Tipp: Addition und Subtraktion).

Uebung 2: Typkonvertierung

Erstelle eine Variable vom Typ double mit dem Wert 9.99. Konvertiere sie in einen int und dann in einen String. Gib alle drei Werte aus.

Uebung 3: Scope verstehen

Was gibt das folgende Programm aus? Ueberlege erst, dann pruefe:

var x = 10;
if (x > 5) {
    var y = 20;
    x = x + y;
}
System.out.println(x);
// System.out.println(y); // Was passiert hier?

Uebung 4: Konstanten-Rechner

Erstelle ein Programm mit Konstanten fuer PI, die Lichtgeschwindigkeit (299792458 m/s) und die Erdbeschleunigung (9.81 m/s^2). Berechne damit den Umfang eines Kreises mit Radius 5.

Was kommt als Naechstes?

In der naechsten Lektion schauen wir uns die primitiven Datentypen im Detail an. Du lernst die Unterschiede zwischen int, long, double, float und den anderen Typen — und wann du welchen verwenden solltest.

Zusammenfassung

  • Variablen brauchen in Java einen festen Typ (int, String, etc.) oder var
  • Lokale Variablen leben in Methoden, Instanzvariablen in Objekten
  • final macht eine Variable unveraenderbar (Konstante)
  • Der Scope bestimmt, wo eine Variable sichtbar ist
  • Primitive Typen speichern Werte direkt, Referenztypen speichern Referenzen
  • Casting konvertiert zwischen Typen ((int) 3.14 ergibt 3)
  • Verwende sprechende Namen und deklariere Variablen so spaet wie moeglich

Pro-Tipp: Nutze var fuer lokale Variablen, wenn der Typ aus dem Kontext klar ist: var liste = new ArrayList<String>() ist lesbarer als ArrayList<String> liste = new ArrayList<String>(). Aber bei var result = getResult() ist unklar, welchen Typ result hat — dann schreibe den Typ lieber explizit hin.

Zurück zum Java Kurs