7

次のコードが期待どおりに機能しないのを見て、私はちょっと困惑しました。

Javaは常に参照によって変数を関数に渡すと思いました。したがって、関数が変数を再割り当てできないのはなぜですか?

public static void main(String[] args) {

  String nullTest = null;

  setNotNull(nullTest);

  System.out.println(nullTest);
}

private static void setNotNull(String s) {
  s = "not null!";
}

このプログラムはを出力しますnull

4

4 に答える 4

22

オブジェクトへの参照はJavaで値によって渡されるため、メソッド内のローカル変数に割り当てても元の変数は変更されません。ローカル変数のみがs新しい文字列を指します。少しのASCIIアートで理解しやすいかもしれません。

最初はこれがあります:

------------
| nullTest |
------------
     |
    null

最初にメソッドsetNotNullを入力すると、のnullTestの値のコピーsを取得します。この場合、nullTestの値はnull参照です。

------------    ------------
| nullTest |    |    s     |
------------    ------------
     |               |
    null            null

次に、sを再割り当てします。

------------    ------------
| nullTest |    |    s     |
------------    ------------
     |               |
    null         "not null!"

そして、メソッドを終了します。

------------
| nullTest |
------------
     |
    null
于 2010-08-14T00:25:34.807 に答える
2

Javaは参照を渡しません。参照の値を渡します。を割り当てるときはs="not null"、その値を再割り当てします。

于 2010-08-14T00:25:40.733 に答える
1

o = setNotNull(o)を使用せずにsetNotNull(MyObject o)のようなことをしたいと思っていました

単純に、できません。あなたが得る最も近いものはこのようなものです:

public class MyRef<T> {
    private T obj;

    public T get() {
        return obj;
    }

    public void set(T obj) {
        this.obj = obj;
    }

    public void setNotNull(T obj) {
        if (this.obj == null) {
            this.obj = obj;
        }
    }
}

MyRef<MyObj> ref = new MyRef<MyObj>();
ref.setNotNull(xyz);
System.err.println(ref.get());

これはすべてかなり不格好で、おそらく努力する価値はありません。

于 2010-08-14T03:03:51.563 に答える
0
s =

これが理由です。sが指すオブジェクトを変更するのではなく、sに割り当てます。

于 2010-08-14T00:28:41.387 に答える