Ich dachte, ich würde diese Antwort beitragen, um weitere Details aus den Spezifikationen hinzuzufügen.
Zuerst, Was ist der Unterschied zwischen dem Übergeben von Referenz vs. dem Übergeben von Wert?
Das Übergeben per Referenz bedeutet, dass der Parameter der aufgerufenen Funktion identisch mit dem vom Aufrufer übergebenen Argument ist (nicht der Wert, sondern die Identität
Das Übergeben per Wert bedeutet, dass der Parameter der aufgerufenen Funktion eine Kopie des vom Aufrufer übergebenen Arguments sein wird.
Oder aus Wikipedia, zum Thema Übergabe per Referenz
Bei der Auswertung per Referenz (auch als Übergabe per Referenz bezeichnet) erhält eine Funktion eine implizite Referenz auf eine Variable, die als Argument verwendet wird, anstatt eine Kopie ihres Werts. Dies bedeutet typischerweise, dass die Funktion die Variable, die als Argument verwendet wird, ändern kann (z.B. zuweisen) - etwas das vom Aufrufer bemerkt wird.
Und zum Thema Übergabe per Wert
Bei der Übergabe per Wert wird der Argumentausdruck ausgewertet und der resultierende Wert wird an die entsprechende Variable in der Funktion gebunden [...]. Wenn die Funktion oder Prozedur in der Lage ist, Werte an ihre Parameter zuzuweisen, wird nur ihre lokale Kopie [...].
Zweitens müssen wir wissen, was Java in seinen Methodenaufrufen verwendet. Die Java Language Specification besagt
Wenn die Methode oder der Konstruktor aufgerufen wird (§15.12), initialisieren die Werte der tatsächlichen Argumentausdrücke neu erstellte Parameter Variablen, jede vom deklarierten Typ, bevor der Körper der Methode oder des Konstruktors ausgeführt wird.
Es weist also den Wert des Arguments der entsprechenden Parametervariable zu.
Was ist der Wert des Arguments?
Lassen Sie uns Referenztypen betrachten, die Java Virtual Machine Specification besagt
Es gibt drei Arten von Referenztypen: Klassentypen, Arraytypen, und Schnittstellentypen. Ihre Werte sind Verweise auf dynamisch erstellte Klasseninstanzen, Arrays oder Klasseninstanzen oder Arrays, die Schnittstellen implementieren, bzw.
Die Java Language Specification besagt auch
Die Referenzwerte (oft nur Verweise) sind Zeiger auf diese Objekte, und ein spezieller Null-Verweis, der auf kein Objekt verweist.
Der Wert eines Arguments (eines Referenztyps) ist ein Zeiger auf ein Objekt. Beachten Sie, dass eine Variable, ein Aufruf einer Methode mit einem Referenztyp-Rückgabetyp und ein Instanzerstellungsausdruck (new ...
) alle zu einem Referenztyp-Wert auflösen.
Also
public void method (String param) {}
...
String variable = new String("ref");
method(variable);
method(variable.toString());
method(new String("ref"));
binden alle den Wert eines Verweises auf eine String
-Instanz an den neu erstellten Parameter der Methode, param
. Dies entspricht genau der Definition von Übergabe per Wert. Daher ist Java Übergabe per Wert.
Die Tatsache, dass Sie dem Verweis folgen können, um eine Methode aufzurufen oder auf ein Feld des referenzierten Objekts zuzugreifen, ist für das Gespräch vollkommen unerheblich. Die Definition von Übergabe per Referenz war
Dies bedeutet typischerweise, dass die Funktion die Variable, die als Argument verwendet wird, ändern kann (z.B. zuweisen) - etwas das vom Aufrufer bemerkt wird.
In Java bedeutet das Ändern der Variable, sie neu zuzuweisen. In Java würde ein erneutes Zuweisen der Variablen innerhalb der Methode vom Aufrufer unbemerkt bleiben. Das Ändern des Objekts, auf das die Variable verweist, ist ein vollständig anderer Konzept.
Primitive Werte sind ebenfalls in der Java Virtual Machine Specification definiert, hier. Der Wert des Typs ist der entsprechende ganze oder Fließkommawert, der entsprechend codiert ist (8, 16, 32, 64, usw. Bits).
6 Stimmen
Wir würden eher sagen, dass eine Variable, die "per Referenz übergeben" wird, verändert werden kann. Der Begriff taucht in Lehrbüchern auf, weil Sprachtheoretiker eine Möglichkeit brauchten, um zu unterscheiden, wie Sie primitive Datentypen (int, bool, byte) von komplexen und strukturierten Objekten (Array, Streams, Klasse) behandeln - das heißt, die möglicherweise ungebundene Speicherzuweisung.
6 Stimmen
Ich möchte darauf hinweisen, dass Sie sich in den meisten Fällen keine Gedanken darüber machen müssen. Ich habe viele Jahre lang Java programmiert, bis ich C ++ gelernt habe. Bis zu diesem Zeitpunkt hatte ich keine Ahnung, was Übergabe nach Referenz und Übergabe nach Wert sind. Die intuitive Lösung hat immer für mich funktioniert, deshalb ist Java eine der besten Sprachen für Anfänger. Wenn Sie sich also gerade Sorgen machen, ob Ihre Funktion eine Referenz oder einen Wert benötigt, übergeben Sie sie einfach so, wie sie ist, und es wird alles in Ordnung sein.
73 Stimmen
Java übergibt die Referenz nach Wert.
21 Stimmen
Ganz knapp gesagt entsteht diese Verwirrung, weil in Java alle Nicht-Primitive Datentypen durch Referenzen behandelt / zugegriffen werden. Allerdings wird immer nach Wert übergeben. Daher wird für alle Nicht-Primitive Typen die Referenz nach seinem Wert übergeben. Auch alle primitiven Typen werden nach Wert übergeben.
6 Stimmen
Ich fand das ziemlich hilfreich: baeldung.com/java-pass-by-value-or-pass-by-reference
1 Stimmen
Es ist der Unterschied zwischen foo.bar(sth) und foo = sth. Im ersten Fall wird das Objekt mit der Variablen, die darauf zeigt, geändert, und die Variable selbst, die auf das Objekt zeigt, wurde nicht geändert. Im zweiten Fall hingegen wurde die Variable selbst, die auf das Objekt zeigt, geändert und zeigt nun auf ein anderes Objekt. Wenn Sie einen Hintergrund in C++ haben: Ein Zeiger ist eine Variable, die eine Speicheradresse enthält, während eine Referenz die gleiche Speicheradresse wie das von ihr referenzierte Element hat. In Java ist tatsächlich ein Zeiger nach Wert übergeben, aber Javaistas nennen es Referenz!
3 Stimmen
Was würde es also bedeuten, wenn eine Sprache eine Referenz nicht nach Wert übergeben würde? Pointer auf Pointer übergeben? Gibt es Sprachen, die so etwas tun? Geben Sprachen wie C/C++ nicht auch Referenzen und Pointer nach Wert weiter??
1 Stimmen
Da Java eine objektorientierte Sprache ist und Objekte per Referenz übergeben werden, entsprechen Änderungen des Objekts gemäß langjährig etablierter Semantik dem Original. Es ist nicht klar, wie sich dieser "pass-by-value"-Unsinn so weit verbreiten konnte.
2 Stimmen
@SamGinrich Java ist immer durch Wertübertragung. Wenn Sie dieses grundlegende Konzept nicht verstehen, das bei weitem nicht so "unsinnig" ist, wie Sie es nennen, empfehle ich Ihnen, die am meisten hoch bewerteten Antworten hier zu lesen, bis Sie verstehen, warum.
0 Stimmen
Für diejenigen, die eine Videoerklärung bevorzugen youtu.be/fL-nXdKWwOg
1 Stimmen
Diese "Objekte werden nach Wert übergeben"-Sache ist irreführend. Referenzen zu Objekten werden übergeben. Nicht kopierte/verschobene Werte von Objekten. Dass die Referenzen selbst nach Wert übergeben werden, ist ein winziges Detail von nicht viel Interesse.
0 Stimmen
@Dalija Prasnikar ... diese Muggelsprache allein! Java ist im Grunde genommen eine objektorientierte Programmiersprache, kein Modus zum Übergeben von Objekten. Selbst wenn Java keine Dereferenzierung unterstützt, ist die Idee, sie als Grundlage für konzeptionelle Diskussionen zu nehmen, genauso fruchtbar wie wenn ein Vegetarier eine Rede bei einer Metzgergilde hält.
1 Stimmen
@SamGinrich Du mischst Äpfel und Birnen. Die Programmiersprachenparadigma allein ist nicht direkt mit den Mechanismen verbunden, die eine Sprache zur Parameterübergabe verwendet. Jeder, der die Funktionsweise von Compilern und Sprachenentwicklung kennt, weiß den Unterschied. Die Terminologie ist universell, weil sie denjenigen, die wissen, was sie bedeutet, eine Bedeutung vermittelt. Nur weil du es ablehnst, die Definition zu lernen, weil es dir keinen Sinn ergibt, bedeutet das nicht, dass es keinen Wert für andere hat, die es verstehen. Ich schlage vor, dass du die beste Antwort sehr sorgfältig liest.
0 Stimmen
@Dalija Prasnikar Sie sind sehr weise und verständnisvoll und haben die Definition, die Ihnen gegeben wurde, fleißig gelernt.
1 Stimmen
@SamGinrich Es geht nicht darum, die Definition wie ein Papagei auswendig zu lernen. Es geht darum zu verstehen, was sie bedeutet und warum solche Definitionen benötigt werden. Definitionen beziehen sich nicht nur auf eine einzige Sprache, sondern auf alle Sprachen. Sie sind wichtig, weil sie das genaue Verhalten in einfachen Worten beschreiben. Wenn man die Worte verdreht, verliert man die präzise Beschreibung dessen, was passiert. Es ist wie in der Mathematik, wo wir einige Definitionen haben, die die Grundlage für alles bilden. Man könnte sagen, dass einige willkürlich gewählt sind und wir die Mathematik auch aus leicht unterschiedlichen begriffen entwickeln könnten, aber dann würde auch alles andere in der Mathematik sich ändern.
0 Stimmen
@Dalija Prasnikar Wie ich oben sagte: "Java ist keine gute Basis, um Dereferenzierung zu verstehen"; trotzdem sind Sie frei, dies zu behaupten. Ich wäre vorsichtig, jemanden als ungebildet zu betrachten, der eine konsistente Meinung zu einem Thema hat.
1 Stimmen
@SamGinrich Konsequenz bedeutet nicht automatisch Wissen. Du kannst konsequent behaupten, dass die Erde flach ist, und du würdest immer noch falsch liegen.
4 Stimmen
Bevor du eine neue Antwort postest, bedenke, dass es bereits 93+ Antworten auf diese Frage gibt. Stelle sicher, dass deine Antwort Informationen enthält, die nicht unter den bereits vorhandenen Antworten zu finden sind. Danke!
0 Stimmen
@Dalija Prasnikar Das Dogma "Java ist pass-by-value" ist ziemlich konsistent, solange man nicht die Grammatik betrachtet. Ich habe gesehen, dass du dich frei gefühlt hast, Beiträge zu löschen, die dieser Regel nicht folgen, dies ist keine Haltung, die die Absicht einer Diskussion widerspiegelt, die offen für Kritik ist. Es gibt gebildete Menschen mit anderen Denkweisen, auch zum Thema. Es sollten bessere Gründe für die Zensur geben und ich hoffe, dass du sie findest.
1 Stimmen
@SamGinrich Meine Moderationsaktivitäten basieren nicht darauf, was mir gefällt oder nicht, sondern auf Korrektheit. Wenn du jedoch Probleme mit den Handlungen einer Person hast oder glaubst, dass ein Beitrag nicht angemessen behandelt wurde, kannst du das immer im Stack Overflow Meta ansprechen. Was diese Frage/Antwort betrifft, habe ich nichts Neues zu sagen, was ich nicht schon gesagt habe.