CodeGym /Kurse /JAVA 25 SELF /Parameterübergabe per Wert und per Referenz

Parameterübergabe per Wert und per Referenz

JAVA 25 SELF
Level 8, Lektion 4
Verfügbar

1. Einleitung

In verschiedenen Programmiersprachen gibt es zwei grundlegende Arten, Parameter an Funktionen (oder Methoden) zu übergeben:

  • Per Wert (Call-by-Value): Die Funktion erhält eine Kopie des Werts der Variablen. Wenn die Funktion den Parameter ändert, bleibt das Original unverändert.
  • Per Referenz (Call-by-Reference): Die Funktion erhält eine „Referenz“ (Zeiger) auf das Originalobjekt. Änderungen innerhalb der Funktion wirken sich auf das Original aus.

In Java werden ALLE Parameter per Wert übergeben!
Aber es gibt einen Haken: Wenn wir primitive Typen (int, double, boolean usw.) übergeben, wird der Wert selbst kopiert. Wenn wir Referenztypen (z. B. Arrays oder Objekte) übergeben, wird der Wert der Referenz (also die „Adresse“ des Objekts im Speicher) kopiert, nicht jedoch das Objekt selbst.

Wenn Sie merken, dass der Kopf raucht, keine Sorge – wir ordnen gleich alles der Reihe nach und zeigen es an Beispielen!

2. Primitive Typen: der Wert wird kopiert

Fangen wir einfach an: Was passiert, wenn wir versuchen, den Wert einer Variable vom Typ int innerhalb einer Methode zu ändern?

public class Demo 
{
    public static void main(String[] args) 
    {
        int number = 5;
        changeValue(number);
        System.out.println(number); // Was wird ausgegeben?
    }

    public static void changeValue(int n) 
    {
        n = 42;
    }
}

Ergebnis: Es wird 5 ausgegeben.

Warum?
In die Methode changeValue wird eine KOPIE des Werts der Variablen number übergeben. Innerhalb der Methode ändern wir nur die Kopie (n); die ursprüngliche Variable number in main bleibt unangetastet.

Analogie
Stellen Sie sich vor, Sie geben einem Freund eine Fotokopie Ihres Ausweises, nicht das Original. Ihr Freund kann auf der Kopie so viele Schnurrbärte malen, wie er möchte – Ihr echter Ausweis bleibt unverändert!

3. Referenztypen: die Referenz wird kopiert

Versuchen wir dasselbe mit einem Array:

public class Demo 
{
    public static void main(String[] args) 
    {
        int[] numbers = {1, 2, 3};
        changeFirst(numbers);
        System.out.println(numbers[0]); // Was wird ausgegeben?
    }

    public static void changeFirst(int[] arr) 
    {
        arr[0] = 99;
    }
}

Ergebnis: Es wird 99 ausgegeben.

Warum?
In die Methode changeFirst wird eine Kopie der REFERENZ auf das Array numbers übergeben. Beide Namen (numbers in main und arr in der Methode) zeigen auf dasselbe Array im Speicher. Deshalb sind Änderungen an Array-Elementen innerhalb der Methode von außen „sichtbar“.

Visualisierung

main: numbers ──► [1, 2, 3]
                   ▲
                   │
changeFirst: arr ──┘
Die Kopie der Referenz zeigt auf dasselbe Objekt im Speicher

Wenn wir arr[0] ändern, ändern wir in Wirklichkeit numbers[0], weil beide auf dasselbe Objekt zeigen.

4. Wenn man jedoch die Referenz selbst ändert — ändert sich das ursprüngliche Objekt nicht!

Versuchen wir nun Folgendes:

public class Demo 
{
    public static void main(String[] args) 
    {
        int[] numbers = {1, 2, 3};
        replaceArray(numbers);
        System.out.println(numbers[0]); // Was wird ausgegeben?
    }

    public static void replaceArray(int[] arr) 
    {
        arr = new int[] {10, 20, 30};
    }
}

Ergebnis: Es wird 1 ausgegeben.

Warum?
In der Methode replaceArray beginnt die Variable arr auf ein neues Array zu zeigen, was jedoch keinen Einfluss auf die Variable numbers in main hat.
Sie waren über dieselbe Referenz verbunden, aber wenn wir innerhalb der Methode arr = ... zuweisen, ist das nur eine lokale Änderung.

Analogie
Es ist, als hätten Sie und Ihr Freund denselben Wohnungsschlüssel. Der Freund macht sich einen neuen Schlüssel, aber Ihr alter Schlüssel bleibt unverändert, und die Tür bleibt dieselbe.

5. Zum Festigen: Man kann zwei int nicht über eine Methode „vertauschen“

Viele Anfänger versuchen, eine Methode zu schreiben, um zwei Zahlen zu vertauschen, aber es klappt nicht:

public class Demo 
{
    public static void main(String[] args) 
    {
        int a = 5, b = 10;
        swap(a, b);
        System.out.println(a + " " + b); // Erwartung: 10 5, aber was tatsächlich?
    }

    public static void swap(int x, int y) 
    {
        int temp = x;
        x = y;
        y = temp;
    }
}

Ergebnis: Es wird 5 10 ausgegeben.

Warum?
Weil in swap nur Kopien der Variablen a und b ankommen. Alles, was wir innerhalb von swap tun, wirkt sich nur auf diese Kopien aus, nicht auf die Originale.

6. Mit Arrays kann man jedoch den Inhalt ändern!

Schauen wir uns die richtige Art an, die Werte in einem Array zu vertauschen:

public class Demo 
{
    public static void main(String[] args) 
    {
        int[] arr = {5, 10};
        swap(arr);
        System.out.println(arr[0] + " " + arr[1]); // Erwartung: 10 5
    }

    public static void swap(int[] arr) 
    {
        int temp = arr[0];
        arr[0] = arr[1];
        arr[1] = temp;
    }
}

Ergebnis: Es wird 10 5 ausgegeben.

Warum?
Weil wir den Inhalt des Objekts (des Arrays) ändern, auf das sowohl die ursprüngliche Variable als auch der Methodenparameter zeigen.

7. Demonstration: Objekte und ihre Felder

Mit Arrays ist es klar. Wie sieht es mit Objekten eigener Klassen aus? Ganz genauso!

class Box 
{
    int value;
}

public class Demo
{
    public static void main(String[] args) 
    {
        Box box = new Box();
        box.value = 7;
        changeBox(box);
        System.out.println(box.value); // Was wird ausgegeben?
    }

    public static void changeBox(Box b) 
    {
        b.value = 42;
    }
}

Ergebnis: Es wird 42 ausgegeben.

Warum?
Weil wir ein Feld des Objekts ändern, auf das die Referenz zeigt.

Was bei der Parameterübergabe an Methoden passiert

Was wird übergeben Wie wird kopiert Im Methodenrumpf änderbar? Von außen sichtbar?
int, double usw. Kopie des Werts Ja, aber nur die Kopie Nein
Array Kopie der Referenz Ja, wenn Elemente geändert werden Ja
Objekt (Klasse) Kopie der Referenz Ja, wenn Felder geändert werden Ja
Array/Objekt Kopie der Referenz Nein, wenn eine neue Referenz zugewiesen wird Nein

8. Typische Fehler

Fehler Nr. 1: Erwartung, dass sich ein int nach dem Methodenaufruf ändert. Viele Anfänger denken, dass man den Wert einer int-Variablen ändern kann, wenn man sie an eine Methode übergibt. Das stimmt nicht: Es ändert sich nur die Kopie!

Fehler Nr. 2: Versuch, zwei int über eine Methode zu vertauschen. Wie wir gesehen haben, ist das unmöglich – nur die Kopien der Variablen werden vertauscht, die Originale bleiben unberührt.

Fehler Nr. 3: Versuch, ein Array über eine Methode „zu ersetzen“. Wenn Sie innerhalb der Methode dem Array-Parameter ein neues Array zuweisen (arr = new int[]{...}), hat das keinen Einfluss auf das Originalarray. Um ein Array „zu ersetzen“, müssen Sie das neue Array aus der Methode zurückgeben und der Variablen im aufrufenden Code zuweisen.

Fehler Nr. 4: Vergessen, dass man den Inhalt eines Objekts ändern kann. Wenn Sie ein Objekt (oder ein Array) übergeben – vergessen Sie nicht, dass alle Änderungen an seinen Feldern/Elementen von außen sichtbar sind!

Fehler Nr. 5: Verwechslungen mit null. Wenn Sie eine Referenz mit dem Wert null an eine Methode übergeben und versuchen, auf deren Felder zuzugreifen, erhalten Sie eine NullPointerException. Seien Sie aufmerksam!

1
Aufgabe
JAVA 25 SELF, Level 8, Lektion 4
Gesperrt
Startpunkt des Roboters auf der Trajektorie zurücksetzen 🤖
Startpunkt des Roboters auf der Trajektorie zurücksetzen 🤖
1
Aufgabe
JAVA 25 SELF, Level 8, Lektion 4
Gesperrt
Versuch, die Bonusliste des Spielers zu aktualisieren 🎁
Versuch, die Bonusliste des Spielers zu aktualisieren 🎁
1
Aufgabe
JAVA 25 SELF, Level 8, Lektion 4
Gesperrt
Spieler in einer Fußballmannschaft vertauschen ⚽
Spieler in einer Fußballmannschaft vertauschen ⚽
1
Aufgabe
JAVA 25 SELF, Level 8, Lektion 4
Gesperrt
Aktualisierung des Inhalts der magischen Truhe 📦
Aktualisierung des Inhalts der magischen Truhe 📦
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION