Java: Übergabe als Referenz oder als Wert? Vollständige Analyse

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Der ewige Kampf "als Referenz" vs "als Wert"



Wenn Sie jemals in Java programmiert und ein Array oder Objekt an eine Methode übergeben haben und sich dann gewundert haben, warum sich die ursprünglichen Daten geändert haben – Sie sind nicht allein. Diese Frage quält Anfänger (und nicht nur sie) seit der Einführung der Sprache. Auf Stack Overflow hat sie Millionen von Aufrufen erhalten, und die Diskussionen in den Kommentaren reißen seit Jahren nicht ab.



Heute klären wir ein für alle Mal: Ist Java "pass-by-reference" oder "pass-by-value"? Spoiler: Die Antwort ist eindeutig, aber der Teufel steckt, wie immer, im Detail. Wir geben nicht nur eine trockene Definition, sondern zeigen anhand realer Beispiele, wie die Argumentübergabe in Java funktioniert und warum viele verwirrt sind.



Was sagen die Entwickler von Java?



Die offizielle Dokumentation und James Gosling selbst (der Entwickler von Java) lassen keinen Raum für Diskussionen: Java übergibt Argumente immer als Wert (pass-by-value). Keine Ausnahmen. Weder für primitive Typen noch für Objekte.



Aber warum ändert der Code dann Objekte? Warum ändert sich ein List oder ein Array, das an eine Methode übergeben wurde? Lassen Sie uns das analysieren.



Pass-by-value: Was bedeutet das überhaupt?



Zunächst eine klare Definition. Pass-by-value bedeutet, dass beim Aufruf einer Methode eine Kopie des Werts der Variablen erstellt wird und genau diese Kopie an die Methode übergeben wird. Die ursprüngliche Variable (im aufrufenden Code) bleibt unberührt.



Pass-by-reference bedeutet, dass der Methode eine Referenz auf die ursprüngliche Variable übergeben wird und die Methode deren Wert direkt ändern kann (z. B. das Objekt ersetzen). So etwas gibt es in Java nicht.



Kommen wir nun zu den Beispielen.



Beispiel 1: Primitive Typen (int, double, boolean)



Bei primitiven Typen ist alles offensichtlich. Schreiben wir einen einfachen Code:



public class Main {    public static void main(String[] args) {        int x = 10;        changePrimitive(x);        System.out.println("Nach der Methode x = " + x); // 10    }

public static void changePrimitive(int value) { value = 20; // ändert die Kopie }}


Ausgabe:

Nach der Methode x = 10


Alles logisch: Wir haben eine Kopie der Zahl 10 übergeben, innerhalb der Methode die Kopie auf 20 geändert, aber das Original blieb unverändert. Dies ist reines pass-by-value.



Beispiel 2: Objekte (Strings, Listen, eigene Klassen)



Und jetzt das Interessante. Schauen Sie:



public class Main {    public static void main(String[] args) {        StringBuilder sb = new StringBuilder("Hallo");        changeStringBuilder(sb);        System.out.println("Nach der Methode: " + sb); // Hallo Welt!    }

public static void changeStringBuilder(StringBuilder builder) { builder.append(" Welt!"); // ändert den Inhalt des Objekts }}


Ausgabe:

Nach der Methode: Hallo Welt!


„Aha! – werden Sie sagen. – Das Objekt hat sich geändert! Also ist es pass-by-reference!“



Nein. Das ist die Falle, in die 90 % der Anfänger tappen. Lassen Sie uns analysieren, was tatsächlich passiert ist.



Was wird in der Variablen sb gespeichert?



In Java speichert eine Variable eines Objekttyps (z. B. StringBuilder, List, String) nicht das Objekt selbst. Sie speichert eine Referenz (Adresse) auf das Objekt im Speicher. Das Objekt selbst befindet sich irgendwo im Heap.



Wenn Sie sb an eine Methode übergeben, übergeben Sie eine Kopie dieser Referenz. Also eine Kopie der Adresse. Sowohl das Original als auch die Kopie zeigen auf dasselbe Objekt. Wenn Sie also über die Kopie der Referenz den Inhalt des Objekts ändern, sind diese Änderungen auch über die ursprüngliche Referenz sichtbar.



Aber! Wenn Sie versuchen, dem Parameter innerhalb der Methode ein neues Objekt zuzuweisen, ändert sich die ursprüngliche Referenz nicht. Beweis:



public class Main {    public static void main(String[] args) {        StringBuilder sb = new StringBuilder("Hallo");        changeReference(sb);        S                

Blogs

Buchempfehlungen