1

someThingメソッドで以下のタイプの既存の変数を上書きする場合、Thingこれを行う正しい方法は何ですか?

doSomething(someThing);

void doSomething(Thing thing){
    //...
    thing = new Thing(...); // receives warning in Eclipse
}

また

someThing = doSomething(someThing);

Thing doSomething(Thing thing){
    //...
    return new Thing(...);
}
4

1 に答える 1

2

someThing最初のサンプルでは、​​呼び出し元の変数は変更されません。割り当てはdoSomethingメソッドでのみ表示されます。

2番目のサンプルはsomeThing、呼び出し元で変更されます。

したがって、発信者を変更したい場合someThingは、オプション2が実行可能ですが、オプション1は実行可能ではありません。

Javaは「参照渡し」または「値渡し」ですか?を参照してください。なぜこれがそのように機能するのか。

次のコードを想定しThing、printメソッドとStringメンバーを持つa。

void foo() {
  Thing one = new Thing("hello");  // 1
  bar(one);
  one.print();                   // 5
}

void bar(Thing two) {            // 2
  two = new Thing("bye");        // 3
}                                // 4

ポイントでの割り当ては、1最初に新しいThingオブジェクトを作成します。

                       Thing{data="hello"}

one次に、それへの参照を:に格納します。

one *----- refs --------v
                       Thing{data="hello"}

barポイントに入る2と、同じオブジェクトへの新しい参照が作成されます。

one *----- refs --------v
                       Thing{data="hello"}
two *----- refs --------^

次に、line3はlineと同じことを行います1。つまり、新しいThingオブジェクトを作成します。

one *----- refs --------v
                       Thing{data="hello"}
two *----- refs --------^

                       Thing{data="bye"}

two次に、その新しいオブジェクトへの参照を:に格納します。

one *----- refs --------v
                       Thing{data="hello"}

two *----- refs --------v
                       Thing{data="bye"}

のみtwoが変更されていることに注意してください。割り当ては、two参照するものを変更します。

から戻るとbar、行4で、twoスコープ外になります。「さようなら」のものには、それを参照するものがなくなります(最終的にはガベージコレクションになります)。

one *----- refs --------v
                       Thing{data="hello"}

                       Thing{data="bye"} // dead, will be collected

したがって、この時点5で、ご覧のとおり、hello印刷されますone。参照するオブジェクトは何も変更されていません。

于 2012-04-20T07:28:45.943 に答える