web-dev-qa-db-ja.com

Javaで参照渡しでパラメーターを渡すことはできますか?

C#の-​​refキーワードに似たセマンティクスが欲しい。

143
ripper234

すべてが値で渡されるであるため、Javaは混乱します。ただし、パラメータ参照型の(つまり、プリミティブ型のパラメータではない)の場合、参照自体は値によって渡されるため、出現 =参照渡しにする(そして、人々はしばしばそうであると主張する)。次のように、これは当てはまりません。

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

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

コンソールにHelloを出力します。上記のコードでGoodbyeを出力する場合のオプションは、次のように明示的な参照を使用です。

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

Javaで参照渡しでパラメーターを渡すことはできますか?

番号。

どうして ? Javaには1つのみメソッドに引数を渡すモード:値によるモードがあります。

注意:

プリミティブの場合、これは簡単に理解できます。値のコピーを取得します。

他のすべての場合、参照のコピーを取得し、これは値渡しでも呼び出されます。

すべてこの写真にあります:

enter image description here

65
PeterMmm

Javaには、言語レベルでrefに似たものは何もありません。 Javaで値セマンティックによる受け渡しのみ

好奇心のために、Javaにref-likeセマンティックを実装して、オブジェクトを可変クラスに単純にラップすることができます。

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();
    }
}

テストケース:

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

「The Java Programming Language」のJames Goslingから:

「... Javaにはパラメーター渡しモードが1つだけあります-値渡し-物事をシンプルに保ちます。.」

18
duffymo

できるとは思わない。最善のオプションは、「参照渡し」で別のクラスインスタンスに渡したいものをカプセル化し、(外部)クラスの参照を(値で)渡すことです。意味がわかると...

つまり、メソッドは渡されたオブジェクトの内部状態を変更し、呼び出し元に見えるようにします。

10
Marc Gravell

Javaは常に値渡しです。

プリミティブを渡すときは値のコピーであり、オブジェクトを渡すときは参照ポインターのコピーです。

7
Nick Holt

別のオプションは、配列を使用することです。 void method(SomeClass[] v) { v[0] = ...; } but 1)メソッドを呼び出す前に配列を初期化する必要がある、2)それでも実装できないこの方法でのスワップ方法...この方法は、JDKで使用されます。 Java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])にあります。

4
Michal Misiak