Heim > Java > JavaErste Schritte > Was ist der Unterschied zwischen der Wertübergabe und der Referenzübergabe in Java?

Was ist der Unterschied zwischen der Wertübergabe und der Referenzübergabe in Java?

青灯夜游
Freigeben: 2023-02-02 15:27:40
Original
5957 Leute haben es durchsucht

Unterschied: 1. Bei der Wertübertragung wird eine Kopie erstellt, während bei der Referenzübertragung keine Kopie erstellt wird. 2. Bei der Wertübertragung kann das Originalobjekt in der Funktion nicht geändert werden, bei der Referenzübertragung kann das Originalobjekt jedoch geändert werden die Funktion. Die Übergabe als Wert bedeutet, dass beim Aufrufen einer Funktion eine Kopie der tatsächlichen Parameter an die Funktion übergeben wird, sodass die tatsächlichen Parameter bei einer Änderung der Parameter in der Funktion nicht beeinträchtigt werden, während die Übergabe als Referenz bedeutet, dass beim Aufrufen der Funktion ein Wert übergeben wird Bei der Funktion wird eine Kopie der tatsächlichen Parameter an die Funktion übergeben. Die Adresse wird direkt an die Funktion übergeben, sodass sich Änderungen an den Parametern in der Funktion auf die tatsächlichen Parameter auswirken.

Was ist der Unterschied zwischen der Wertübergabe und der Referenzübergabe in Java?

Die Betriebsumgebung dieses Tutorials: Windows7-System, Java8-Version, DELL G3-Computer.

Aktuelle und formale Parameter

Wir alle wissen, dass Parameter definiert werden können, wenn eine Methode in Java definiert wird. Zum Beispiel die Hauptmethode in Java, public static void main(String[ ] args), die Argumente hier sind Parameter. Parameter werden in Programmiersprachen in Formalparameter und Aktualparameter unterteilt.

  • Formale Parameter: sind die Parameter, die beim Definieren des Funktionsnamens und des Funktionskörpers verwendet werden. Der Zweck besteht darin, die beim Aufruf der Funktion übergebenen Parameter zu empfangen.

  • Aktuelle Parameter: Beim Aufruf einer parametrisierten Funktion besteht eine Datenübertragungsbeziehung zwischen der aufrufenden Funktion und der aufgerufenen Funktion. Beim Aufrufen einer Funktion in der aufrufenden Funktion werden die Parameter in Klammern nach dem Funktionsnamen als „tatsächliche Parameter“ bezeichnet Parameter sind Parameter, die zum Empfangen des Inhalts tatsächlicher Parameter verwendet werden.

Wertübergabe und Referenzübergabe

Wie oben erwähnt, werden beim Aufruf einer parametrisierten Funktion die tatsächlichen Parameter an die formalen Parameter übergeben. In Programmiersprachen gibt es bei diesem Übertragungsprozess jedoch zwei Fälle von Übertragungen, nämlich die Übertragung durch Wert und die Übertragung durch Referenz. Werfen wir einen Blick darauf, wie die Wertübergabe und die Referenzübergabe in Programmiersprachen definiert und unterschieden werden.

Wertübergabe bedeutet, die tatsächlichen Parameter zu kopieren und beim Aufrufen der Funktion an die Funktion zu übergeben, sodass die tatsächlichen Parameter nicht beeinträchtigt werden, wenn die Parameter in der Funktion geändert werden.

Übergabe als Referenz

bedeutet, dass die Adresse der tatsächlichen Parameter beim Aufruf der Funktion direkt an die Funktion übergeben wird. Dann wirken sich die Änderungen an den Parametern in der Funktion auf die tatsächlichen Parameter aus.

Mit den oben genannten Konzepten können Sie dann Code schreiben und ihn üben, um zu sehen, ob es sich um eine Wertübergabe oder eine Referenzübergabe in Java handelt. So kam der einfachste Code heraus:

public static void main( String[ ] args) {
ParamTest pt = new ParamTest();
pt.sout( "Hollis");//实际参数为Hollis
}
public void sout( String name) {/!形式参数为name
system.out.println(name);
}
Nach dem Login kopieren

Im obigen Code haben wir den Wert von Parameter j wird in der Pass-Methode geändert, und dann wird der Wert des Parameters in der Pass-Methode bzw. der Main-Methode gedruckt. Das Ausgabeergebnis lautet wie folgt:
public static void main( String[] args) {
     ParamTest pt = new ParamTest();
    int i = 10;
    pt.pass(i);
    System.out.println( "print in main , i is " +i);
}
public void pass(int j){
    j = 20;
    system.out.println( "print in pass , j is " + j);
}
Nach dem Login kopieren
Es ​​ist ersichtlich, dass die Änderung des Werts von i innerhalb der Pass-Methode den Wert des tatsächlichen Parameters i nicht ändert. Gemäß der obigen Definition kam jemand zu dem Schluss: Die Methodenübergabe in Java ist die Wertübergabe.

Einige Leute stellten jedoch bald Fragen (haha, also ziehen Sie keine voreiligen Schlüsse). Dann verschieben sie den folgenden Code:

print in pass , j is 20
print in main , i is 10
Nach dem Login kopieren

ist auch eine Übergabemethode, und der Wert des Parameters wird auch innerhalb der Übergabemethode geändert. Das Ausgabeergebnis lautet wie folgt:

public static void main(String[ ] args) {
    ParamTest pt = new ParamTest();
    User hollis = new User();
    hollis.setName( "Hollis");
    hollis.setGender("Male");
    pt.pass(hollis);
    system.out.println( "print in main , user is " + hollis);}public void pass(User user) {
    user.setName( "hollischuang");
    System.out.println( "print in pass , user is " + user);}
Nach dem Login kopieren

Nachdem die Übergabemethode ausgeführt wurde, wird der Wert des tatsächlichen Parameters gemäß der obigen Definition der Übergabe als Referenz geändert als Referenz übergeben? Daher kam jemand auf der Grundlage der beiden oben genannten Codeteile zu einer neuen Schlussfolgerung: In Java-Methoden erfolgt die Übergabe gewöhnlicher Typen als Wert und bei der Übergabe von Objekttypen als Referenz.

Allerdings ist diese Aussage immer noch falsch. Wenn Sie mir nicht glauben, schauen Sie sich die folgende Parameterübertragung an, bei der der Parametertyp ein Objekt ist:

print in pass , user is User{name='hollischuang', gender='Male '}
print in main , user is User{name='hollischuang' , gender='Male '}
Nach dem Login kopieren

Das Ausgabeergebnis des obigen Codes ist

public static void main( string[] args) {
    ParamTest pt = new ParamTest();
    string name = "Hollis";
    pt.pass(name ) ;
    System.out.println( "print in main , name is " + name);
}
public void pass(string name) {
    name = "hollischuang";
    system.out.println( "print in pass , name is " + name);
}
Nach dem Login kopieren

Was ist die Erklärung? Es wird auch ein Objekt übergeben, aber das Wird der Wert des ursprünglichen Parameters nicht geändert? Objekte wurden erneut als Wert übergeben? Oben haben wir drei Beispiele angegeben, aber die Ergebnisse sind auch bei vielen Anfängern unterschiedlich und selbst viele fortgeschrittene Programmierer haben verwirrende Gründe für die Übergabe von Java-Typen. Tatsächlich möchte ich Ihnen sagen, dass das obige Konzept nicht falsch ist, aber es gibt ein Problem mit dem Codebeispiel. Lassen Sie mich Ihnen die Kernpunkte des Konzepts erläutern und Ihnen dann ein paar wirklich passende Beispiele nennen.


Wertübergabe

bedeutet, die tatsächlichen Parameter zu kopieren und beim Aufrufen der Funktion an die Funktion zu übergeben, sodass die tatsächlichen Parameter nicht beeinträchtigt werden, wenn die Parameter in der Funktion geändert werden.

Übergabe als Referenz

bedeutet, dass die Adresse der tatsächlichen Parameter beim Aufruf der Funktion direkt an die Funktion übergeben wird. Dann wirken sich die Änderungen an den Parametern in der Funktion auf die tatsächlichen Parameter aus.

Lassen Sie mich für Sie die wichtigsten Punkte des Unterschieds zwischen Wertübergabe und Referenzübergabe zusammenfassen.


Wertübergabe Referenzübergabe

Der grundlegende Unterschied Alle. Funktionen können nicht geändert werden Die Funktion „Originalobjekt

erstellt eine Kopie
erstellt keine Kopie
“ kann das Originalobjekt ändern

我们上面看过的几个pass的例子中,都只关注了实际参数内容是否有改变。如传递的是User对象,我们试着改变他的name属性的值,然后检查是否有改变。其实,在实验方法上就错了,当然得到的结论也就有问题了。

为什么说实验方法错了呢?这里我们来举一个形象的例子。再来深入理解一下值传递和引用传递,然后你就知道为啥错了。

你有一把钥匙,当你的朋友想要去你家的时候,如果你直接把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。

你有一把钥匙,当你的朋友想要去你家的时候,你复刻了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。

但是,不管上面那种情况,你的朋友拿着你给他的钥匙,进到你的家里,把你家的电视砸了。那你说你会不会受到影响?而我们在pass方法中,改变user对象的name属性的值的时候,不就是在“砸电视”么。

还拿上面的一个例子来举例,我们真正的改变参数,看看会发生什么?

public static void main(String[ ] args){
    ParamTest pt = new ParamTest();
    User hollis = new User();
    hollis.setName( "Hollis");
    hollis.setGender("Male" );
    pt.pass(hollis);
    system.out.println("print in main , user is " + hollis);
    public void pass(User user) {
        user = new User();
        user.setName( "hollischuang");
        user.setGender( "Male");
        system.out.println( "print in pass , user is " + user);
Nach dem Login kopieren

上面的代码中,我们在pass方法中,改变了user对象,输出结果如下:

print in pass , user is User{name='hollischuang ' , gender='Male '}
print in main , user is User{name='Hollis', gender= 'Male '}
Nach dem Login kopieren

我们来画一张图,看一下整个过程中发生了什么,然后我再告诉你,为啥Java中只有值传递。

Was ist der Unterschied zwischen der Wertübergabe und der Referenzübergabe in Java?

稍微解释下这张图,当我们在main中创建一个User对象的时候,在堆中开辟一块内存,其中保存了name和gender等数据。然后hollis持有该内存的地址ex123456(图1)。当尝试调用pass方法,并且hollis作为实际参数传递给形式参数user的时候,会把这个地址ex123456交给user,这时,user也指向了这个地址(图2)。然后在pass方法内对参数进行修改的时候,即user = newUser();,会重新开辟一块 eX456789的内存,赋值给user。后面对user的任何修改都不会改变内存eX123456的内容(图3)。

上面这种传递是什么传递?肯定不是引用传递,如果是引用传递的话,在user=new User()的时候,实际参数的引用也应该改为指向eX456789,但是实际上并没有。

通过概念我们也能知道,这里是把实际参数的引用的地址复制了一份,传递给了形式参数。所以,上面的参数其实是值传递,把实参对象引用的地址当做值传递给了形式参数。

我们再来回顾下之前的那个“砸电视”的例子,看那个例子中的传递过程发生了什么。

Was ist der Unterschied zwischen der Wertübergabe und der Referenzübergabe in Java?

同样的,在参数传递的过程中,实际参数的地址eX1213456被拷贝给了形参,只是,在这个方法中,并没有对形参本身进行修改,而是修改的形参持有的地址中存储的内容。

所以,值传递和引用传递的区别并不是传递的内容。而是实参到底有没有被复制一份给形参。在判断实参内容有没有受影响的时候,要看传的的是什么,如果你传递的是个地址,那么就看这个地址的变化会不会有影响,而不是看地址指向的对象的变化。就像钥匙和房子的关系。

那么,既然这样,为啥上面同样是传递对象,传递的String对象和User对象的表现结果不一样呢?我们在pass方法中使用name = “hollischuang”;试着去更改name的值,阴差阳错的直接改变了name的引用的地址。因为这段代码,会new一个String,在把引用交给name,即等价于name =new String(“hollischuang”);。而原来的那个”Hollis”字符串还是由实参持有着的,所以,并没有修改到实际参数的值。

Was ist der Unterschied zwischen der Wertübergabe und der Referenzübergabe in Java?

所以说,Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。

总结

无论是值传递还是引用传递,其实都是一种求值策略(Evaluation strategy)。在求值策略中,还有一种叫做按共享传递。其实Java中的参数传递严格意义上说应该是按共享传递。

Übergabe durch gemeinsame Nutzung bedeutet, dass beim Aufruf einer Funktion eine Kopie der Adresse des tatsächlichen Parameters an die Funktion übergeben wird (wenn sich der tatsächliche Parameter auf dem Stapel befindet, wird der Wert direkt kopiert). Wenn Sie Parameter innerhalb einer Funktion bearbeiten, müssen Sie die Adresse kopieren, um den spezifischen Wert vor der Operation zu finden. Wenn sich der Wert auf dem Stapel befindet, wirken sich Operationen an den Parametern innerhalb der Funktion nicht auf externe Variablen aus, da es sich um eine direkte Kopie des Werts handelt. Wenn es sich bei der Originalkopie um die Adresse des Originalwerts im Heap handelt, müssen Sie vor dem Ausführen des Vorgangs anhand der Adresse den entsprechenden Speicherort im Heap finden. Da eine Kopie der Adresse übergeben wird, ist die Operation am Wert innerhalb der Funktion für die externe Variable sichtbar.

Einfach ausgedrückt erfolgt die Übertragung in Java nach Wert, und dieser Wert ist tatsächlich eine Referenz auf ein Objekt.
Das Passing-by-Sharing ist eigentlich nur ein Sonderfall des Passing-by-Value. Wir können also sagen, dass die Übergabe in Java eine Übergabe durch Teilen ist, oder dass die Übergabe in Java eine Übergabe durch Wert ist.

Betriebsparameter innerhalb der Funktion haben also keinen Einfluss auf externe Variablen. Wenn es sich bei der Originalkopie um die Adresse des Originalwerts im Heap handelt, müssen Sie vor dem Ausführen des Vorgangs anhand der Adresse den entsprechenden Speicherort im Heap finden. Da eine Kopie der Adresse übergeben wird, ist die Operation am Wert innerhalb der Funktion für die externe Variable sichtbar.

Einfach ausgedrückt erfolgt die Übertragung in Java nach Wert, und dieser Wert ist tatsächlich eine Referenz auf ein Objekt.

Und das Passing-by-Sharing ist eigentlich nur ein Sonderfall des Passing-by-Value. Wir können also sagen, dass die Übergabe in Java eine Übergabe durch Teilen ist, oder dass die Übergabe in Java eine Übergabe durch Wert ist.

Weitere Kenntnisse zum Thema Programmierung finden Sie unter: Programmierunterricht! !

Das obige ist der detaillierte Inhalt vonWas ist der Unterschied zwischen der Wertübergabe und der Referenzübergabe in Java?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage