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 ──┘
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!
GO TO FULL VERSION