Bevor Sie diesen Artikel lesen, können Sie basierend auf Ihrer eigenen Erfahrung und Ihrem Verständnis zunächst über die Parameterübergabemethode von Java-Funktionen nachdenken und diese auswählen:
A. Wird es als Wert übergeben?
B. Durch Verweis weitergegeben?
C. Teils nach Wert, teils nach Referenz?
Die richtige Antwort wird hier noch nicht bekannt gegeben. Wir lassen Sie die Antwort anhand eines einfachen Beispiels selbst finden:
1. Definieren Sie zunächst einen Typwert
public static class Value { private String value = "value"; public String getValue() { return value } public void setValue(String value) { this.value = value;
2. Schreiben Sie zwei Funktionen NewValue und ModifyValue: NewValue zeigt den Eingabeparameter auf ein neues Objekt und ModifyValue ruft die SetValue-Methode des Eingabeparameters auf, um den Wert des Objekts zu ändern.
public static void newValue(Value value) { value = new Value(); value.setValue("new value"); System.out.println("In newValue, HashCode = " + value.hashCode() + ", value = " + value.getValue()); } public static void changesValue(Value value) { value.setValue("new value"); System.out.println("In changesValue, HashCode = " + value.hashCode() + ", value = " + value.getValue()); }
3. Einfacher Testcode
public static void main(String[] args) { Value value1 = new Value(); System.out.println("Vor der Änderung, HashCode = " + value1.hashCode() + ", value = " + value1.getValue() ); // Wert1 auf das neue Wertobjekt verweisen newValue(value1); System.out.println("Nach der Änderung, HashCode = " + value1.hashCode() + ", value = " + value1.getValue() + "/n"); Value value2 = new Value(); System.out.println("Vor dem Ändern, HashCode = " + value2.hashCode() + ", value = " + value2.getValue()); // Verwenden Sie die Set-Methode des Objekts, um den internen Wert des Objekts zu ändern changesValue(value2); System.out.println("Nach der Änderung wird HashCode = " + value2.hashCode() + ", value = " + value2.getValue() }
4. Ausführungsergebnisprotokoll:
Vor dem Ändern, HashCode = 12677476, Wert = Wert. In newValue, HashCode = 33263331, Wert = neuer Wert. Nach dem Ändern, HashCode = 12677476, Wert = Wert. Vor dem Ändern, HashCode = 6413875, Wert = Wert. In changesValue, HashCode = 6413875, Wert = neuer Wert Nach der Änderung ist HashCode = 6413875, Wert = neuer Wert
5. Ergebnisanalyse:
Der obige Code ist ein sehr häufiges Programmiermuster: Definieren Sie einen Wert oder ein Objekt in der Peripherie, übergeben Sie das Objekt als Parameter an eine Methode und ändern Sie die Eigenschaften und das Verhalten des Objekts in der Methode. Allerdings sind die Änderungsmethoden der beiden Methoden newValue und changesValue unterschiedlich. Nach dem Aufruf der Methode sieht das Objekt von außen ganz anders aus! Wie ist dieser Unterschied zu verstehen? Sehen wir uns zunächst die Konzepte der Wertübergabe und der Referenzübergabe an:
* Wertübergabe bedeutet, dass die Funktion eine Kopie des ursprünglichen Werts erhält, wenn Sie ein Argument an eine Funktion übergeben. Wenn die Funktion den Parameter ändert, wird daher nur die Kopie geändert, während der ursprüngliche Wert unverändert bleibt.
* Die Übergabe als Referenz bedeutet, dass die Funktion bei der Übergabe eines Arguments an eine Funktion die Speicheradresse des ursprünglichen Werts und nicht eine Kopie des Werts erhält. Wenn die Funktion den Parameter ändert, ändert sich daher auch der ursprüngliche Wert des Parameters (im aufrufenden Code außerhalb des Funktionsblocks).
Richtige Antwort: A – Java-Funktionen übergeben Parameter als Wert!
Analysieren Sie das Protokoll:
* Im ersten Abschnitt der Protokollausgabe wird der Parameter value1 so geändert, dass er auf ein neues Objekt innerhalb der newValue-Methode verweist, und der HashCode und der Wert des neuen Objekts werden ausgegeben. Nach dem Springen aus der newValue-Methodendomäne erfolgt jedoch keine Änderung tritt in der Hauptmethode auf value1 auf Dies entspricht der Definition und den Merkmalen der Wertübergabe; wenn es als Referenz übergeben wird, sollte sich value1 nach dem Aufruf der Methode newValue(Value value) ändern.
* Die zweite Protokollausgabe zeigt, dass value2 eine setValue-Operation innerhalb der Methode „modifyValue“ ausführt. Der HashCode bleibt unverändert, aber der Wert wird geändert. Nach dem Verlassen der „modifyValue“-Methodendomäne ändert sich „value2“ in der Hauptmethode. Leute, die C++ verwendet haben, können dieses Phänomen leicht verstehen als: Funktionsparameter als Referenz übergeben! Weil dies der Referenzübergabe in C++ sehr ähnlich ist! Doch genau hier kommt es am ehesten zu Missverständnissen!
Das verborgene Prinzip hinter den unterschiedlichen Phänomenen der beiden Protokolle besteht darin, dass die Java-Sprache Parameter als Wert und Objekte als Referenz übergibt. Die in Java betriebenen Objekte sind tatsächlich Verweise auf die Betriebsobjekte und die Objekte selbst werden im „Heap“ gespeichert. und die „Referenz“ des Objekts wird in einem Register oder „Stapel“ gespeichert.
Pseudocode beschreibt den Unterschied zwischen der newValue-Methode und der changesValue-Methode:
newValue{ Value_ref2 = value_ref1; // Übergeben Sie die Referenz value_ref1 und erhalten Sie eine Kopie von value_ref1 value_obj2 = new Value(); // value_obj2 wird im „Heap“ erstellt und initialisiert value_ref2 -> value_obj2; value_obj2 value_ref2 - >value_obj2.setValue(“xxx”); // value_obj2 Der Wert wird geändert printValueObj2(); // Was hier gedruckt wird, ist der Wert von obj2} changesValue{ Value_ref2 = value_ref1; // Übergeben Sie die Referenz value_ref1 nach value und erhalten Sie eine Kopie von value_ref1 value_ref2 ->value_obj1.setValue("xxx "); // Der Wert von value_obj1 wird geändert printValueObj1(); // Was hier gedruckt wird, ist der Wert von obj1}
Das ist klar genug! Wenn value1_ref1 als Parameter an die Funktion übergeben wird, wird zunächst eine Kopie von value1_ref2 zur Verwendung in der Funktionsdomäne kopiert. Zu diesem Zeitpunkt verweisen beide Refs auf denselben value_obj-Code in der newObject-Funktion [value = new Value(); ] Tatsächlich zeigt value1_ref1 auf ein neues Objekt value_obj2; die Set-Operationen danach sind alle Operationen für das neue Objekt, die value_obj1 direkt über die Set-Methode ausführen, was sich von der newValue-Funktion unterscheidet.
Übergeben Sie Parameter nach Wert
Beim Aufrufen einer Methode müssen Sie Parameter angeben, und zwar in der in der Parameterliste angegebenen Reihenfolge.
Die folgende Methode gibt beispielsweise eine Nachricht n-mal hintereinander aus:
public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) System.out.println(message);}
Beispiel Das folgende Beispiel demonstriert die Auswirkung der Wertübergabe.
Dieses Programm erstellt eine Methode, die zwei Variablen austauscht.
public class TestPassByValue { public static void main(String[] args) { int num1 = 1; int num2 = 2; System.out.println("Vor der Swap-Methode ist num1 " + num1 + " und num2 ist " + num2) ; // Rufen Sie die Swap-Methode auf swap(num1, num2); System.out.println("Nach der Swap-Methode ist num1 " + num1 + " und num2 ist " + num2); } /** Methode zum Austauschen zweier Variablen*/ public static void swap(int n1, int n2) { System.out.println("/tInside the swap method"); .out.println("/t/tBefore swapping n1 is " + n1 + " n2 is " + n2); // Vertausche die Werte von n1 und n2 int temp = n1; n2; n2 = temp; System.out.println("/t/tNach dem Austausch von n1 ist " + n1 + " n2 ist " + n2 }}
Die Kompilierungs- und Ausführungsergebnisse des obigen Beispiels lauten wie folgt:
Vor der Swap-Methode ist num1 1 und num2 2. Innerhalb der Swap-Methode ist n1 vor dem Swap 1, n2 ist 2. Nach dem Swap ist n1 2 und n2 ist 1. Nach der Swap-Methode ist num1 1 und num2 2
Rufen Sie die Swap-Methode auf und übergeben Sie dabei zwei Parameter. Interessanterweise ändern sich die Werte der tatsächlichen Parameter nach dem Aufruf der Methode nicht.