it-swarm.com.de

Kann ich in Java Parameter als Referenz übergeben?

Ich hätte gerne eine ähnliche Semantik wie C# 's ref Schlüsselwort.

143
ripper234

Java ist verwirrend, weil alles wird als Wert übergeben. Für einen Parameter des Referenztyps (dh keinen Parameter des primitiven Typs) ist es jedoch die Referenz selbst das als Wert übergeben wird, daher scheint es als Referenzübergabe zu gelten (und die Leute behaupten oft, dass dies der Fall ist) . Dies ist nicht der Fall, wie im Folgenden gezeigt:

Object o = "Hello";
mutate(o)
System.out.println(o);

private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!

Gibt Hello auf der Konsole aus. Wenn Sie möchten, dass der obige Code Goodbye druckt, müssen Sie einen expliziten Verweis wie folgt verwenden:

AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!

private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
222
oxbow_lakes

Kann ich in Java Parameter als Referenz übergeben?

Nein.

Warum ? Java hat nur einen Modus zum Übergeben von Argumenten an Methoden: nach Wert.

Hinweis:

Für Primitive ist dies leicht zu verstehen: Sie erhalten eine Kopie des Werts.

Für alle anderen erhalten Sie eine Kopie der Referenz und diese wird auch als Wertübergabe bezeichnet.

Es ist alles auf diesem Bild:

enter image description here

65
PeterMmm

In Java gibt es auf Sprachniveau nichts Ähnliches wie ref. In Java es wird nur eine Wertesemantik übergeben)

Aus Gründen der 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"
23
dfa

Von James Gosling in "The Java Programming Language"):

"... In Java - Übergeben nach Wert - gibt es genau einen Parameterübergabemodus, der die Dinge einfach hält. .."

18
duffymo

Ich glaube nicht, dass du kannst. Am besten kapseln Sie das Objekt, das Sie als "by ref" übergeben möchten, in eine andere Klasseninstanz und übergeben die Referenz der (äußeren) Klasse (nach Wert). Wenn du verstehst was ich meine...

d.h. Ihre Methode ändert den internen Zustand des Objekts, an das sie übergeben wird, und ist dann für den Aufrufer sichtbar.

10
Marc Gravell

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.

7
Nick Holt

Eine andere Option ist die Verwendung eines Arrays, z. void method(SomeClass[] v) { v[0] = ...; }, aber 1) das Array muss initialisiert werden, bevor die Methode aufgerufen wird, 2) es kann immer noch nicht implementiert werden, z. Swap-Methode auf diese Weise ... Diese Methode wird in JDK verwendet, z. in Java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]).

4
Michal Misiak