Heim  >  Artikel  >  Java  >  Eine eingehende Analyse der Methodenparameterübergabe in der Java-Programmierung

Eine eingehende Analyse der Methodenparameterübergabe in der Java-Programmierung

高洛峰
高洛峰Original
2017-01-19 15:11:121105Durchsuche

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 sie als Wert übergeben?
B. Als Referenz übergeben?
C. Teils nach Wert und teils nach Referenz?
Die richtige Antwort wird hier noch nicht bekannt gegeben, damit jeder die Antwort selbst finden kann:
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 modifyValue(Value value) {
  value.setValue("new value");
  System.out.println("In modifyValue, HashCode = " + value.hashCode() + ", value = " + value.getValue());
}

3. Einfacher Testcode

public static void main(String[] args) {
  Value value1 = new Value();
  System.out.println("Before modify, HashCode = " + value1.hashCode() + ", value = " + value1.getValue());
  // 将value1指向新的Value对象
  newValue(value1);
  System.out.println("After modify, HashCode = " + value1.hashCode() + ", value = " + value1.getValue() + "\n");
  Value value2 = new Value();
  System.out.println("Before modify, HashCode = " + value2.hashCode() + ", value = " + value2.getValue());
  // 使用object的set方法,修改对象的内部值
  modifyValue(value2);
  System.out.println("After modify, HashCode = " + value2.hashCode() + ", value = " + value2.getValue());
}

4. Ausführungsergebnisprotokoll:

Before modify, HashCode = 12677476, value = value
In newValue, HashCode = 33263331, value = new value
After modify, HashCode = 12677476, value = value
  
Before modify, HashCode = 6413875, value = value
In modifyValue, HashCode = 6413875, value = new value
After modify, HashCode = 6413875, value = new value

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 des Objekts in Methode. ,Verhalten. 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 bei der Übergabe eines Parameters an eine Funktion eine Kopie des Originalwerts erhält. Wenn die Funktion den Parameter ändert, wird daher nur die Kopie geändert, während der ursprüngliche Wert unverändert bleibt.
* Übergabe als Referenz bedeutet, dass die Funktion bei der Übergabe eines Arguments an eine Funktion die Speicheradresse des ursprünglichen Werts und keine 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 nach Wert!
Analysieren Sie das Protokoll:
* In der ersten Protokollausgabe wird der Parameter value1 so geändert, dass er auf das neue Objekt innerhalb der newValue-Methode zeigt, und der HashCode und der Wert des neuen Objekts werden ausgegeben, jedoch nach dem Herausspringen In der Methodendomäne newValue gibt es im Wesentlichen keine Änderung an Wert1 in der Methode, was mit der Definition und den Merkmalen der Wertübergabe übereinstimmt. Wenn er als Referenz übergeben wird, sollte sich Wert1 nach dem Aufruf der Methode newValue(Wertwert) ändern .
* In der zweiten Protokollausgabe führt value2 eine SetValue-Operation innerhalb der Methode „modifyValue“ aus. Der HashCode bleibt unverändert, aber der Wert wird geändert. Nach dem Verlassen der Domäne „modifyValue“ ä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 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 das Objekt selbst wird im „Heap“ gespeichert. , während die „Referenz“ des Objekts in einem Register oder „Stapel“ gespeichert wird.
Pseudocode beschreibt den Unterschied zwischen der newValue-Methode und der changesValue-Methode:

newValue{
  Value_ref2 = value_ref1;  // 按值传入引用value_ref1,得到value_ref1的副本
  value_obj2 = new Value();  // value_obj2被创建、初始化在“堆“中
  value_ref2 -> value_obj2;  // value_ref2 指向value_obj2
value_ref2 ->value_obj2.setValue(“xxx”); // value_obj2 的value被修改
printValueObj2();      // 此处打印的是obj2的值
}
modifyValue{
  Value_ref2 = value_ref1;  // 按值传入引用value_ref1,得到value_ref1的副本
value_ref2 ->value_obj1.setValue(“xxx”); // value_obj1 的value被修改
printValueObj1();      // 此处打印的是obj1的值
}

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.

Parameter nach Wert übergeben
Wenn Sie eine Methode aufrufen, müssen Sie Parameter angeben, und zwar in der in der Parameterliste angegebenen Reihenfolge.
Zum Beispiel gibt die folgende Methode 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 zeigt die Auswirkung der Wertübergabe.
Dieses Programm erstellt eine Methode, die zum Austausch zweier Variablen verwendet wird.

public class TestPassByValue {
 
  public static void main(String[] args) {
   int num1 = 1;
   int num2 = 2;
 
   System.out.println("Before swap method, num1 is " +
             num1 + " and num2 is " + num2);
 
   // 调用swap方法
   swap(num1, num2);
   System.out.println("After swap method, num1 is " +
             num1 + " and num2 is " + num2);
  }
  /** 交换两个变量的方法 */
  public static void swap(int n1, int n2) {
   System.out.println("\tInside the swap method");
   System.out.println("\t\tBefore swapping n1 is " + n1
              + " n2 is " + n2);
   // 交换 n1 与 n2的值
   int temp = n1;
   n1 = n2;
   n2 = temp;
 
   System.out.println("\t\tAfter swapping n1 is " + n1
              + " n2 is " + n2);
  }
}

Die Kompilierungs- und Ausführungsergebnisse des obigen Beispiels lauten wie folgt:

Before swap method, num1 is 1 and num2 is 2
    Inside the swap method
        Before swapping n1 is 1 n2 is 2
        After swapping n1 is 2 n2 is 1
After swap method, num1 is 1 and num2 is 2

Pass Die Swap-Methode wird mit zwei Parametern aufgerufen. Interessanterweise ändern sich die Werte der tatsächlichen Parameter nach dem Aufruf der Methode nicht.

Für eine tiefergehende Analyse der Parameterübergabe von Methoden in der Java-Programmierung beachten Sie bitte die chinesische PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn