Java ist verwirrend, weil alles als Wert übergeben wird . Für einen Parameter vom Referenztyp (dh keinen Parameter vom primitiven Typ) ist es jedoch die Referenz selbst, die als Wert übergeben wird, daher scheint es sich um eine Referenzübergabe zu handeln (und die Leute behaupten oft, dass dies der Fall ist). Dies ist nicht der Fall, wie Folgendes zeigt:
Object o ="Hello";
mutate(o)System.out.println(o);privatevoid mutate(Object o){ o ="Goodbye";}//NOT THE SAME o!
Wird Helloauf der Konsole gedruckt . Wenn Sie möchten, dass der obige Code gedruckt Goodbyewird, verwenden Sie eine explizite Referenz wie folgt:
Außerdem kann ein Array der Länge 1 verwendet werden, um eine Referenz zu erstellen, wenn Sie die Leute wirklich verwirren möchten :)
Christoffer
2
AtomicReference und entsprechende Klassen (AtomicInteger) eignen sich am besten für solche Operationen
Naveen
3
AtomicReference ist ein Overkill, Sie wollen dort nicht unbedingt eine Speicherbarriere, und sie könnten Sie kosten. JRuby hatte ein Leistungsproblem aufgrund einer flüchtigen Variablen, die beim Erstellen eines Objekts verwendet wurde. Die Option, Array als Ad-hoc-Referenz zu verwenden, scheint mir gut genug zu sein, und ich habe gesehen, dass es mehr als einmal verwendet wurde.
Elazar Leibovich
Ich denke nicht, dass dies verwirrend ist, dies ist jedoch ein normales Verhalten. Werttypen existieren auf dem Stapel und Referenztypen existieren auf dem Heap, aber Verweise auf Referenztypen existieren auch auf dem Stapel. Sie arbeiten also immer mit dem Wert, der sich auf dem Stapel befindet. Ich glaube, die Frage hier war: Ist es möglich, eine Referenz vom Stapel zu übergeben, die auf einen anderen Wert verweist, der sich ebenfalls auf dem Stapel befindet? Oder eine Referenz einer anderen Referenz übergeben, die auf einen Wert verweist, der auf einem Haufen lebt?
Eomeroff
das ich tolle info. Ich hatte Arrays verwendet, aber dies scheint etwas für den Job gebaut zu sein. Ich weiß nicht über die Leistung dieses Arrays im
Vergleich zu
65
Kann ich Parameter in Java als Referenz übergeben?
Nein.
Warum ? Java hat nur einen Modus zum Übergeben von Argumenten an Methoden: nach Wert.
Hinweis:
Für Grundelemente ist dies leicht zu verstehen: Sie erhalten eine Kopie des Werts.
Für alle anderen erhalten Sie eine Kopie der Referenz, die auch als Wertübergabe bezeichnet wird.
Warum nicht stattdessen java.lang.ref.Reference verwenden?
Hardcoded
java.lang.ref.Reference hat keine festgelegte Methode, sie ist nicht veränderbar
dfa
warum nicht verwenden AtomicReference(für Nicht-Primitive)? Oder AtomicSomething(zB :) AtomicBooleanfür Primitive?
Arvin
Leider akzeptiert <T> keine primitiven Typen. Möchte dies tun: Ref <int>
jk7
1
@ jk7 Ist es wirklich wichtig genug, intstatt Integer, boolstatt Booleanund so weiter verwenden zu müssen? Das heißt, Wrapper-Klassen (die automatisch entpackt werden, wenn Sie sich Gedanken über die Syntax machen) funktionieren nicht?
Paul Stelian
18
Von James Gosling in "The Java Programming Language":
"... In Java gibt es genau einen Parameterübergabemodus - Übergabe nach Wert - und das hält die Dinge einfach. ..."
Die Aussprache des Sprachgottes sollte zur Antwort erklärt werden.
Ingyhere
3
@ingyhere :: The pronouncement of the language god should be declared the answerNicht wirklich. Ungeachtet dessen, was der Schöpfer von Java denkt oder glaubt, würde die absolute Antwort aus einem Zitat aus der Sprachspezifikation stammen.
Paercebal
1
In der Tat ist es in den JLS, in Abschnitt 8.4.1 und die JLS zitiert Gosling als erster Autor: „Wenn das Verfahren oder der Konstruktor aufgerufen wird (§15.12) Initialisieren der Werte der Ist - Argument Ausdrücke neu Parametervariablen erstellt , von denen jede vom deklarierten Typ vor der Ausführung des Hauptteils der Methode oder des Konstruktors. "
Ingyhere
Genau. Sarkasmus von Mitgliedern mit geringen Wiederholungszahlen ist nicht hilfreich.
Duffymo
11
Ich glaube nicht, dass du kannst. Ihre beste Option könnte darin bestehen, das Objekt, das Sie "by ref" an eine andere Klasseninstanz übergeben möchten, zu kapseln und die Referenz der (äußeren) Klasse (nach Wert) zu übergeben. Wenn du verstehst was ich meine...
Das heißt, Ihre Methode ändert den internen Status des übergebenen Objekts, das dann für den Aufrufer sichtbar ist.
Eine andere Möglichkeit ist die Verwendung eines Arrays, z. B.
void method(SomeClass[] v) { v[0] = ...; }
1) das Array muss vor dem Aufrufen der Methode initialisiert werden, 2) man kann zB die Swap-Methode noch nicht auf diese Weise implementieren ... Diese Art wird in JDK verwendet, z java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]). B. in .
Antworten:
Java ist verwirrend, weil alles als Wert übergeben wird . Für einen Parameter vom Referenztyp (dh keinen Parameter vom primitiven Typ) ist es jedoch die Referenz selbst, die als Wert übergeben wird, daher scheint es sich um eine Referenzübergabe zu handeln (und die Leute behaupten oft, dass dies der Fall ist). Dies ist nicht der Fall, wie Folgendes zeigt:
Wird
Hello
auf der Konsole gedruckt . Wenn Sie möchten, dass der obige Code gedrucktGoodbye
wird, verwenden Sie eine explizite Referenz wie folgt:quelle
Nein.
Warum ? Java hat nur einen Modus zum Übergeben von Argumenten an Methoden: nach Wert.
Hinweis:
Für Grundelemente ist dies leicht zu verstehen: Sie erhalten eine Kopie des Werts.
Für alle anderen erhalten Sie eine Kopie der Referenz, die auch als Wertübergabe bezeichnet wird.
Es ist alles auf diesem Bild:
quelle
In Java gibt es auf Sprachebene nichts Vergleichbares wie ref . In Java wird nur die Wertesemantik übergeben
Aus Neugier können Sie eine ref-ähnliche Semantik in Java implementieren, indem Sie Ihre Objekte einfach in eine veränderbare Klasse einschließen:
Testfall:
quelle
AtomicReference
(für Nicht-Primitive)? OderAtomicSomething
(zB :)AtomicBoolean
für Primitive?int
stattInteger
,bool
stattBoolean
und so weiter verwenden zu müssen? Das heißt, Wrapper-Klassen (die automatisch entpackt werden, wenn Sie sich Gedanken über die Syntax machen) funktionieren nicht?Von James Gosling in "The Java Programming Language":
quelle
The pronouncement of the language god should be declared the answer
Nicht wirklich. Ungeachtet dessen, was der Schöpfer von Java denkt oder glaubt, würde die absolute Antwort aus einem Zitat aus der Sprachspezifikation stammen.Ich glaube nicht, dass du kannst. Ihre beste Option könnte darin bestehen, das Objekt, das Sie "by ref" an eine andere Klasseninstanz übergeben möchten, zu kapseln und die Referenz der (äußeren) Klasse (nach Wert) zu übergeben. Wenn du verstehst was ich meine...
Das heißt, Ihre Methode ändert den internen Status des übergebenen Objekts, das dann für den Aufrufer sichtbar ist.
quelle
Java wird immer als Wert übergeben.
Wenn Sie ein Grundelement übergeben, ist es eine Kopie des Werts. Wenn Sie ein Objekt übergeben, ist es eine Kopie des Referenzzeigers.
quelle
Eine andere Möglichkeit ist die Verwendung eines Arrays, z. B.
void method(SomeClass[] v) { v[0] = ...; }
1) das Array muss vor dem Aufrufen der Methode initialisiert werden, 2) man kann zB die Swap-Methode noch nicht auf diese Weise implementieren ... Diese Art wird in JDK verwendet, zjava.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])
. B. in .quelle