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:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Wird Hello
auf der Konsole gedruckt . Wenn Sie möchten, dass der obige Code gedruckt Goodbye
wird, verwenden Sie eine explizite Referenz wie folgt:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
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.
Es ist alles auf diesem Bild:
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:
public class Ref<T> {
private T value;
public Ref(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T anotherValue) {
value = anotherValue;
}
@Override
public String toString() {
return value.toString();
}
@Override
public boolean equals(Object obj) {
return value.equals(obj);
}
@Override
public int hashCode() {
return value.hashCode();
}
}
Testfall:
public void changeRef(Ref<String> ref) {
ref.set("bbb");
}
// ...
Ref<String> ref = new Ref<String>("aaa");
changeRef(ref);
System.out.println(ref); // prints "bbb"
AtomicReference
(für Nicht-Primitive)? Oder AtomicSomething
(zB :) AtomicBoolean
für Primitive?
int
statt Integer
, bool
statt Boolean
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":
"... In Java gibt es genau einen Parameterübergabemodus - Übergabe nach Wert - und das hält die Dinge einfach. ..."
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.
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 .