Ich versuche, zwei Zeichenfolgen in Java zu tauschen. Ich habe nie wirklich verstanden "Strings sind unveränderlich". Ich verstehe es in der Theorie, aber ich bin nie in der Praxis darauf gestoßen.
Da String ein Objekt in Java ist und kein primitiver Typ, verstehe ich nicht, warum der folgende Code das gleiche Ergebnis zweimal ausgibt, anstatt die Wörter zu vertauschen!
%Vor%Ich möchte, dass es gedruckt wird
%Vor%Aber es ist Drucken
%Vor%Ich dachte s1 und s2 sind Referenzen und daher sollten die Referenzen getauscht werden und die neuen sollten jeweils auf die andere verweisen. Wo gehe ich falsch?
Ich dachte s1 und s2 sind Referenzen und daher sollten die Referenzen getauscht werden und die neuen sollten jeweils auf die andere verweisen.
Ja. Lokal innerhalb swap
, genau das passiert.
Allerdings sind s1
und s2
Kopien der Referenzen, die an die Funktion übergeben werden, so dass der Effekt lokal bleibt. Beachten Sie, dass nicht die Strings kopiert werden (da String
ein Referenztyp ist). Aber die Referenzen werden kopiert.
... und da Parameterreferenzen immer in Java kopiert werden, ist es ganz einfach nicht möglich, eine swap
-Funktion gemäß Ihren Spezifikationen zu schreiben.
Wenn Sie Probleme haben, den Unterschied zu verstehen, denken Sie darüber nach: Sie möchten einen Brief an einen Freund schreiben, damit Sie ihre Adresse aus Ihrem Adressbuch auf einen Umschlag kopieren. Durch diesen Prozess hast du sie sicher nicht nach Hause kopiert (das Kopieren eines ganzen Hauses ist in der Praxis etwas schwierig) - du hast nur die Adresse kopiert.
Nun, eine Adresse bezieht sich auf ihr Zuhause, also ist es genau wie eine Java-Referenz.
Der folgende Code ist ein NoGo . Implementiere niemals dieses Anti-Pattern, ändere niemals jemals private finale Interna in unveränderlichen Objekten. Tadeln Sie mich nicht dafür, diesen Hack zu zeigen, tadeln Sie Oracle's jvm dafür, es nicht zu verbieten.
Aber, wenn Sie eines Tages Code finden, wo dies funktioniert:
%Vor% Die Implementierung von swap
könnte so aussehen: (Lesen Sie auf eigene Gefahr, ich warnte Sie!)
Grundsätzlich können Sie die Methode swap
in Java nicht implementieren.
Der Grund, warum Sie dies nicht tun können, ist, dass das Java-Argument eine Pass-by-Value-Argument-Semantik hat. Wenn also Ihre swap
-Methode s2
auf s1
usw. zuweist, funktioniert sie vollständig auf den lokalen Variablen s1
und s2
und nicht auf den s1
und s2
Variablen in der aufrufenden Methode main
.
Wenn Sie hingegen die Methode swap
in C implementieren, sieht das etwa so aus:
und Sie würden es so nennen:
%Vor%Beachten Sie, dass wir tatsächlich die Adresse einer Variable "Zeiger auf Char" übergeben.
In Java können Sie dies nicht tun, weil Sie die Adresse einer Variablen nicht übernehmen können. Es wird einfach nicht unterstützt.
Es gab kürzlich eine sehr ähnliche Frage über den Austausch von zwei Ints. Und meine Antwort war dann Verwenden Sie atomare Referenzen :
%Vor%Das ist natürlich nicht sehr befriedigend, da Sie sich kaum gegen AtomicReferences entwickeln. Aber im Grunde müssen Sie eine Art Container verwenden, da Sie die Referenzen nicht einfach austauschen können. So können Sie z.B. Tauschen Sie die Elemente eines Arrays oder einer Liste mit zwei Elementen aus, aber Sie können nur zwei Strings austauschen, ohne Zugriff auf die ursprünglichen Variablen zu haben (Sie können dies also nicht in einer Hilfsfunktion tun).
Die Variablen s1 und s2 in Ihrem Funktionswap sind lokal für diese Funktion.
Sie müssen s1 und s2 als private Variablen für Ihre Klasse definieren oder ein Array von Strings aus Ihrer Funktion zurückgeben.
Da Java pass-by-value verwendet, führt die von Ihnen definierte swap-Funktion keinen Swapping durch; Die Zeiger s1 und s2 werden lokal ausgetauscht, aber das Ergebnis des Tausches bleibt nicht erhalten. Die nächste Sache, die Sie erreichen können, besteht darin, die Elemente, die Sie austauschen möchten, in eine Klasse zu verpacken und eine Swap-Methode in dieser Klasse zu definieren. Dadurch können Sie Daten zwischen Instanzen dieser Klasse austauschen, obwohl die zugrunde liegenden Daten nicht tatsächlich ausgetauscht werden. Als ein Beispiel dafür:
%Vor% Mit StringBufferReader
und StringBuilder
kann dies gelöst werden. Bei 1. Holen Sie die Werte vom Benutzer, dann teilen Sie sie und speichern Sie sie in Array. Führen Sie die for-Schleife in umgekehrter Reihenfolge aus, so dass die letzte Zeichenfolge angehängt und angezeigt wird, die erste wird als letzte angezeigt.
Eingabe: Hallo Welt
Ausgabe:
Tags und Links string java pass-by-reference