Methodenaufruf (Call by) ist ein Standardbegriff in der Informatik. Methodenaufrufe werden entsprechend der übergebenen Parameter in Wertaufrufe (Call by Reference) und Referenzaufrufe (Call by Value) unterteilt. Es gibt weltweit viele Definitionen dieser beiden Arten von Aufrufen. Die häufigste Aussage ist, dass derjenige, der den Wert übergibt, ein Wertaufruf ist und derjenige, der die Adresse übergibt, ein Referenzaufruf ist. Dies ist eigentlich sehr unangemessen. Diese Anweisungen erinnern uns leicht daran, dass die Übergabe von Objektparametern in Java ein Referenzaufruf ist.
Lassen Sie uns zunächst einen Code verwenden, um zu überprüfen, warum die Übergabe von Objektparametern in Java nach Wert aufgerufen wird.
public class Employee { public String name=null; public Employee(String n){ this.name=n; } //将两个Employee对象交换 public static void swap(Employee e1,Employee e2){ Employee temp=e1; e1=e2; e2=temp; System.out.println(e1.name+" "+e2.name); //打印结果:李四 张三 } //主函数 public static void main(String[] args) { Employee worker=new Employee("张三"); Employee manager=new Employee("李四"); swap(worker,manager); System.out.println(worker.name+" "+manager.name); //打印结果仍然是: 张三 李四 } }
Das obige Ergebnis ist sehr enttäuschend. Obwohl die Inhalte der formalen Parameterobjekte e1 und e2 ausgetauscht wurden, gilt dies für die tatsächlichen Parameterobjekte Worker und Manager nicht. Inhalte austauschen. Der wichtigste Grund hierfür ist, dass die formalen Parameter e1 und e2 Adresskopien der tatsächlichen Parameter Worker und Manager sind.
Wie wir alle wissen, stellt der Objektvariablenname in Java tatsächlich die Adresse des Objekts im Heap dar (der Fachbegriff heißt Objektreferenz). Beim Aufruf einer Java-Methode ist der übergebene Parameter eine Referenz auf das Objekt. Wichtig ist, dass die von formalen Parametern und tatsächlichen Parametern belegten Speicheradressen nicht identisch sind. Der Inhalt in den formalen Parametern ist lediglich eine Kopie der in den tatsächlichen Parametern gespeicherten Objektreferenz.
Wenn Sie etwas über den lokalen Variablenbereich des Java-Stacks in der JVM-Speicherverwaltung wissen (siehe „Java Virtual Machine Architecture“), können Sie den obigen Satz leicht verstehen. Wenn die JVM das obige Programm ausführt, werden durch die Ausführung der Hauptmethode und der Swap-Methode zwei Speicherbereiche, sogenannte Stapelrahmen, im Java-Stack verschoben. Im Hauptstapelrahmen gibt es einen Speicherbereich namens „Lokaler Variablenbereich“, in dem Verweise auf die eigentlichen Parameterobjekte „Worker“ und „Manager“ gespeichert werden. Der lokale Variablenbereich im Swap-Stack-Frame speichert Referenzen auf die formalen Parameterobjekte e1 und e2. Obwohl die Referenzwerte von e1 und e2 mit denen von Arbeiter und Manager identisch sind, belegen sie unterschiedliche Speicherplätze. Wenn die Referenzen von e1 und e2 ausgetauscht werden, zeigt die folgende Abbildung deutlich, dass die Referenzwerte von Arbeiter und Manager überhaupt nicht beeinflusst werden.
Obwohl die Übergabe von Java-Objektparametern eine Adresse (Referenz) übergibt, handelt es sich immer noch um einen Wertaufruf. Es ist an der Zeit, eine genaue Definition von Call-by-Reference und Call-by-Value zu geben.
Aufruf nach Wert: Während der Parameterübergabe belegen Formalparameter und Aktualparameter zwei völlig unterschiedliche Speicherbereiche. Der im Formalparameter gespeicherte Inhalt ist eine Kopie des im Aktualparameter gespeicherten Inhalts. Tatsächlich entspricht die Übertragung von Java-Objekten dieser Definition, mit der Ausnahme, dass der in den Formalparametern und Aktualparametern gespeicherte Inhalt nicht der Variablenwert im herkömmlichen Sinne, sondern die Adresse der Variablen ist. Ähem, denken Sie zurück und denken Sie darüber nach: Ist die Adresse einer Variablen nicht auch ein Wert?
Call-by-Reference: Bei der Parameterübertragung liegen die formalen Parameter und die tatsächlichen Parameter vollständig im selben Speicherbereich und sind nicht voneinander getrennt. Tatsächlich sind formale Parameternamen und tatsächliche Parameternamen nur unterschiedliche Symbole in der Programmierung. Während der Ausführung des Programms ist der Speicherplatz im Speicher am wichtigsten. Unterschiedliche Variablennamen bedeuten nicht, dass der belegte Speicherplatz unterschiedlich ist.
Im Allgemeinen besteht der grundlegende Unterschied zwischen den beiden Aufrufen nicht darin, ob der Wert oder die Adresse übergeben wird (schließlich ist die Adresse auch ein Wert), sondern darin, ob die formalen Parameter und die tatsächlichen Parameter denselben Speicher belegen Raum. Tatsächlich ist die Übergabe von Zeigerparametern in C/C++ auch ein Wertaufruf. Wenn Sie es nicht glauben, versuchen Sie es mit dem folgenden C-Code!
#include<stdio.h> void swap(int *a1,int *b1){ int *t=a1; a1=b1; b1=t; } int main(){ int x1=100; int x2=200; int *a=&x1; int *b=&x2; printf("%d %d\n",*a,*b); swap(a,b); printf("%d %d\n",*a,*b); return 0; }
Aber C/C++ wird durch Referenz aufgerufen. Dies ist eine Variablendeklarationsmethode namens Referenz in C/C++: int a; wobei ra ist Es gibt keinen Unterschied zwischen den beiden Aliasnamen im Speicher und sie belegen denselben Speicherplatz. Die Parameterübergabe per Referenz (Alias) entspricht den Merkmalen des Referenzaufrufs. Sie können die Operationsergebnisse von void swap(int &a1,int &b1); ausprobieren.
Durch diesen Artikel sollten Sie wissen, ob Java-Methodenparameter per Referenz oder per Wert aufgerufen werden.
Weitere Artikel darüber, ob Java-Methodenparameter Referenzaufrufe oder Wertaufrufe sind, finden Sie auf der chinesischen PHP-Website!