Call by Reference: Unterschied zwischen den Versionen
Hauer (Diskussion | Beiträge) (→Beispiel) |
Hauer (Diskussion | Beiträge) (→Beispiel) |
||
Zeile 22: | Zeile 22: | ||
In diesem Beispiel deklarieren wir eine Variable mit dem Namen <code>x</code>, welche eine Referenz auf ein <code>NumberStorage</code> Objekt speichert. Diese Variable wird mit einer Referenz auf ein neues Objekt initialisiert. Der gespeicherte Wert ist 5. Der anschließende Aufruf der Funktion <code>callee</code> (Zeile 4) hat nun Einfluss auf das übergebene Objekt: Es wird die Referenz auf das erzeugte Objekt, welches momentan in <code>x</code> gespeichert ist, übergeben. Die Änderung des Wertes dieses Objektes in <code>callee</code> hat dadurch auch Einfluss auf die Variable <code>x</code>, da die Variablen <code>a</code> und <code>x</code> (momentan) auf das gleiche Objekt verweisen. Entsprechend ist der Wert des Objektes hinter <code>x</code> nach Aufruf der Funktion <code>callee</code> nun '''3''' anstatt '''5''', anders als bei [[Call by Value]]. Das öffentliche zugänglichmachen des <code>value</code>-Attributes ist dabei zugegebenermaßen schlechter Stil. | In diesem Beispiel deklarieren wir eine Variable mit dem Namen <code>x</code>, welche eine Referenz auf ein <code>NumberStorage</code> Objekt speichert. Diese Variable wird mit einer Referenz auf ein neues Objekt initialisiert. Der gespeicherte Wert ist 5. Der anschließende Aufruf der Funktion <code>callee</code> (Zeile 4) hat nun Einfluss auf das übergebene Objekt: Es wird die Referenz auf das erzeugte Objekt, welches momentan in <code>x</code> gespeichert ist, übergeben. Die Änderung des Wertes dieses Objektes in <code>callee</code> hat dadurch auch Einfluss auf die Variable <code>x</code>, da die Variablen <code>a</code> und <code>x</code> (momentan) auf das gleiche Objekt verweisen. Entsprechend ist der Wert des Objektes hinter <code>x</code> nach Aufruf der Funktion <code>callee</code> nun '''3''' anstatt '''5''', anders als bei [[Call by Value]]. Das öffentliche zugänglichmachen des <code>value</code>-Attributes ist dabei zugegebenermaßen schlechter Stil. | ||
− | <source lang="java"> | + | <source lang="java" title="Negativbeispiel"> |
public static void caller(){ | public static void caller(){ | ||
NumberStorage x = new NumberStorage(5); //Arbiträres Objekt, das eine Zahl speichert. | NumberStorage x = new NumberStorage(5); //Arbiträres Objekt, das eine Zahl speichert. | ||
− | System.out.println("x: "+x. | + | System.out.println("x: "+x.value); //Gibt aus: "x: 5" |
callee(x); //Übergibt die Referenz von x and callee (Call by Reference) | callee(x); //Übergibt die Referenz von x and callee (Call by Reference) | ||
− | System.out.println("x: "+x. | + | System.out.println("x: "+x.value); //Gibt aus: "x: 3" |
} | } | ||
public static void callee(NumberStorage a){ | public static void callee(NumberStorage a){ | ||
− | a. | + | a.value = 3; //Setzt den Wert des übergebenen Objektes auf 3 |
a = new NumberStorage(8); //Erzeugt ein neues Objekt und überschreibt die lokale Referenz | a = new NumberStorage(8); //Erzeugt ein neues Objekt und überschreibt die lokale Referenz | ||
} | } | ||
</source> | </source> | ||
− | Hier | + | Hier wird noch ein mal verdeutlicht, dass Variablen mit Objektdatentyp nur Referenzen auf Objekte speichern. Eine Änderung der von <code>a</code> gespeicherten Referenz in <code>callee</code> hat daher wie bei [[Call by Value]] keinen Einfluss auf die aufrufende Funktion <code>caller</code>. |
Version vom 26. September 2016, 17:25 Uhr
Unter Call by Reference versteht man das Übergeben von Objektreferenzen an Methoden.
Eine Variable mit einem Objektdatentyp speichert nicht das Objekt selbst, sondern nur eine Referenz auf dieses Objekt. Wird also eine Objektvariable an eine Methode übergeben, wird nur eine Kopie der Referenz auf ein Objekt übergeben, nicht jedoch eine Kopie des Objektes selbst. Dadurch haben anschließende Änderungen an Attributen des Objektes in der aufgerufenen Methode Einfluss auf die Attribute des Objektes außerhalb der Methode.
Alle Variablen, die dieselbe Referenz besitzen, erfahren dadurch die Änderungen an dem Objekt hinter der Referenz. Dies steht im Kontrast zu Variablen mit primitivem Datentyp. Ihr Wert wird immer direkt übergeben und nicht die Referenz auf den Speicherbereich, in dem der Wert zu finden ist (siehe Call by Value).
Beispiel
public static void caller(){ NumberStorage x = new NumberStorage(5); //Arbiträres Objekt, das eine Zahl speichert. System.out.println("x: "+x.value); //Gibt aus: "x: 5" callee(x); //Übergibt die Referenz von x and callee (Call by Reference) System.out.println("x: "+x.value); //Gibt aus: "x: 3" } public static void callee(NumberStorage a){ a.value = 3; //Setzt den Wert des übergebenen Objektes auf 3 }
In diesem Beispiel deklarieren wir eine Variable mit dem Namen x
, welche eine Referenz auf ein NumberStorage
Objekt speichert. Diese Variable wird mit einer Referenz auf ein neues Objekt initialisiert. Der gespeicherte Wert ist 5. Der anschließende Aufruf der Funktion callee
(Zeile 4) hat nun Einfluss auf das übergebene Objekt: Es wird die Referenz auf das erzeugte Objekt, welches momentan in x
gespeichert ist, übergeben. Die Änderung des Wertes dieses Objektes in callee
hat dadurch auch Einfluss auf die Variable x
, da die Variablen a
und x
(momentan) auf das gleiche Objekt verweisen. Entsprechend ist der Wert des Objektes hinter x
nach Aufruf der Funktion callee
nun 3 anstatt 5, anders als bei Call by Value. Das öffentliche zugänglichmachen des value
-Attributes ist dabei zugegebenermaßen schlechter Stil.
public static void caller(){ NumberStorage x = new NumberStorage(5); //Arbiträres Objekt, das eine Zahl speichert. System.out.println("x: "+x.value); //Gibt aus: "x: 5" callee(x); //Übergibt die Referenz von x and callee (Call by Reference) System.out.println("x: "+x.value); //Gibt aus: "x: 3" } public static void callee(NumberStorage a){ a.value = 3; //Setzt den Wert des übergebenen Objektes auf 3 a = new NumberStorage(8); //Erzeugt ein neues Objekt und überschreibt die lokale Referenz }
Hier wird noch ein mal verdeutlicht, dass Variablen mit Objektdatentyp nur Referenzen auf Objekte speichern. Eine Änderung der von a
gespeicherten Referenz in callee
hat daher wie bei Call by Value keinen Einfluss auf die aufrufende Funktion caller
.