Pass-By-Value als Parameterübergabemechanismus in Java

1. Einleitung

Die beiden am häufigsten verwendeten Modi zum Übergeben von Argumenten an Methoden sind "Übergeben nach Wert" und "Übergeben nach Referenz". Verschiedene Programmiersprachen verwenden diese Konzepte auf unterschiedliche Weise. In Bezug auf Java ist alles streng pass-by-Value .

In diesem Tutorial werden wir veranschaulichen, wie Java Argumente für verschiedene Typen übergibt.

2. Pass-by-Value vs Pass-by-Reference

Beginnen wir mit einigen der verschiedenen Mechanismen zum Übergeben von Parametern an Funktionen:

  • Wert
  • Referenz
  • Ergebnis
  • Wertergebnis
  • Name

Die beiden häufigsten Mechanismen in modernen Programmiersprachen sind "Pass-by-Value" und "Pass-by-Reference". Bevor wir fortfahren, wollen wir zuerst diese diskutieren:

2.1. Pass-by-Value

Wenn ein Parameter als Wert übergeben wird, arbeiten der Aufrufer und die Angerufene-Methode mit zwei verschiedenen Variablen, die Kopien voneinander sind. Änderungen an einer Variablen ändern die andere nicht.

Dies bedeutet, dass beim Aufrufen einer Methode an die Callee-Methode übergebene Parameter Klone der ursprünglichen Parameter sind. Änderungen an der Callee-Methode haben keine Auswirkungen auf die ursprünglichen Parameter der Caller-Methode.

2.2. Pass-by-Reference

Wenn ein Parameter als Referenz übergeben wird, arbeiten der Anrufer und der Angerufene an demselben Objekt.

Dies bedeutet, dass bei einer Referenzübergabe einer Variablen die eindeutige Kennung des Objekts an die Methode gesendet wird. Alle Änderungen an den Instanzmitgliedern des Parameters führen dazu, dass diese Änderung am ursprünglichen Wert vorgenommen wird.

3. Parameterübergabe in Java

Die grundlegenden Konzepte in jeder Programmiersprache sind "Werte" und "Referenzen". In Java speichern primitive Variablen die tatsächlichen Werte, während Nicht-primitive Variablen die Referenzvariablen speichern, die auf die Adressen der Objekte verweisen, auf die sie sich beziehen. Sowohl Werte als auch Referenzen werden im Stapelspeicher gespeichert.

Argumente in Java werden immer als Wert übergeben. Während des Methodenaufrufs wird im Stapelspeicher eine Kopie jedes Arguments erstellt, unabhängig davon, ob es sich um einen Wert oder eine Referenz handelt, die dann an die Methode übergeben wird.

Bei Grundelementen wird der Wert einfach in den Stapelspeicher kopiert und dann an die Angerufene-Methode übergeben. Bei Nicht-Grundelementen verweist eine Referenz im Stapelspeicher auf die tatsächlichen Daten, die sich im Heap befinden. Wenn wir ein Objekt übergeben, wird die Referenz im Stapelspeicher kopiert und die neue Referenz an die Methode übergeben.

Lassen Sie uns dies nun anhand einiger Codebeispiele in Aktion sehen.

3.1. Primitive Typen übergeben

Die Java-Programmiersprache bietet acht primitive Datentypen. Primitive Variablen werden direkt im Stapelspeicher gespeichert. Immer wenn eine Variable des primitiven Datentyps als Argument übergeben wird, werden die tatsächlichen Parameter in formale Argumente kopiert, und diese formalen Argumente sammeln ihren eigenen Speicherplatz im Stapelspeicher.

Die Lebensdauer dieser formalen Parameter dauert nur so lange, wie diese Methode ausgeführt wird. Bei der Rückgabe werden diese formalen Argumente aus dem Stapel entfernt und verworfen.

Versuchen wir es anhand eines Codebeispiels zu verstehen:

public class PrimitivesUnitTest { @Test public void whenModifyingPrimitives_thenOriginalValuesNotModified() { int x = 1; int y = 2; // Before Modification assertEquals(x, 1); assertEquals(y, 2); modify(x, y); // After Modification assertEquals(x, 1); assertEquals(y, 2); } public static void modify(int x1, int y1) { x1 = 5; y1 = 10; } } 

Versuchen wir, die Aussagen im obigen Programm zu verstehen, indem wir analysieren, wie diese Werte im Speicher gespeichert sind:

  1. Die Variablen " x" und " y" in der Hauptmethode sind primitive Typen und ihre Werte werden direkt im Stapelspeicher gespeichert
  2. Wenn wir die Methode modify () aufrufen , wird für jede dieser Variablen eine genaue Kopie erstellt und an einer anderen Stelle im Stapelspeicher gespeichert
  3. Jede Änderung dieser Kopien wirkt sich nur auf sie aus und lässt die ursprünglichen Variablen unverändert

3.2. Objektreferenzen übergeben

In Java werden alle Objekte dynamisch im Heap-Bereich unter der Haube gespeichert. Diese Objekte werden aus Referenzen referenziert, die als Referenzvariablen bezeichnet werden.

Ein Java-Objekt wird im Gegensatz zu Primitiven in zwei Schritten gespeichert. Die Referenzvariablen werden im Stapelspeicher gespeichert, und das Objekt, auf das sie sich beziehen, wird in einem Heapspeicher gespeichert.

Immer wenn ein Objekt als Argument übergeben wird, wird eine genaue Kopie der Referenzvariablen erstellt, die auf dieselbe Position des Objekts im Heapspeicher verweist wie die ursprüngliche Referenzvariable.

Infolgedessen wird diese Änderung immer dann, wenn wir Änderungen an demselben Objekt in der Methode vornehmen, im ursprünglichen Objekt wiedergegeben. Wenn wir der übergebenen Referenzvariablen jedoch ein neues Objekt zuweisen, wird es nicht im ursprünglichen Objekt wiedergegeben.

Versuchen wir dies anhand eines Codebeispiels zu verstehen:

public class NonPrimitivesUnitTest { @Test public void whenModifyingObjects_thenOriginalObjectChanged() { Foo a = new Foo(1); Foo b = new Foo(1); // Before Modification assertEquals(a.num, 1); assertEquals(b.num, 1); modify(a, b); // After Modification assertEquals(a.num, 2); assertEquals(b.num, 1); } public static void modify(Foo a1, Foo b1) { a1.num++; b1 = new Foo(1); b1.num++; } } class Foo { public int num; public Foo(int num) { this.num = num; } }

Lassen Sie uns die Aussagen im obigen Programm analysieren. Wir haben die Objekte a und b in der Methode " modify () " übergeben, die denselben Wert 1 hat . Anfänglich verweisen diese Objektreferenzen auf zwei unterschiedliche Objektpositionen in einem Heap-Bereich:

Wenn diese Referenzen a und b in der Methode modify () übergeben werden, werden Spiegelkopien der Referenzen a1 und b1 erstellt, die auf dieselben alten Objekte verweisen:

Wenn wir in der Methode modify () die Referenz a1 ändern , ändert sich das ursprüngliche Objekt. Für eine Referenz b1 haben wir jedoch ein neues Objekt zugewiesen. Es zeigt jetzt auf ein neues Objekt im Heapspeicher.

Änderungen an b1 spiegeln nichts im Originalobjekt wider:

4. Fazit

In diesem Artikel haben wir uns angesehen, wie die Parameterübergabe bei Primitiven und Nicht-Primitiven behandelt wird.

Wir haben gelernt, dass die Parameterübergabe in Java immer "Pass-by-Value" ist. Der Kontext ändert sich jedoch abhängig davon, ob es sich um Grundelemente oder Objekte handelt:

  1. Bei primitiven Typen werden Parameter als Wert übergeben
  2. Bei Objekttypen lautet die Objektreferenz "Wert übergeben"

Die in diesem Artikel verwendeten Codefragmente finden Sie auf GitHub.