電子書籍の厳選無料作品が豊富!

f(sba,sbb)を実行後のsbbの出力結果に疑問があります。sbaの引数をsb1で受け取ったのを編集しても、sbaで出力しているので変数が違うから当然出力結果に変化がないのは頷けますが、なぜsb2.append("ddddd");では変数をsbbで出力させているのに、sbbの結果が反映されているのかが分かりません。
実行結果
sba = aaaaa
sbb = bbbbb
sba = aaaaa
sbb = bbbbbddddd
返答のほどよろしくお願いいたします。
class Arguments{
public static void main(String args[]){
StringBuffer sba = new StringBuffer("aaaaa");
StringBuffer sbb = new StringBuffer("bbbbb");

System.out.println("sba = " + sba);
System.out.println("sbb = " + sbb);
f(sba,sbb);

System.out.println("sba = " + sba);
System.out.println("sbb = " + sbb);
}
public static void f(StringBuffer sb1, StringBuffer sb2){
sb1 = new StringBuffer("ccccc");
sb2.append("ddddd");
}
}

A 回答 (2件)

Javaにはポインタは無いと言いますが。



Javaでオブジェクトを引数として関数を呼び出すと、関数にはオブジェクトの参照が渡されます。ポインタのようなものですね。

mainの中でまず以下の代入文が実行されますよね。
 StringBuffer sba = new StringBuffer("aaaaa");
 StringBuffer sbb = new StringBuffer("bbbbb");
ここでメモリ内は下のような状態になっています。
 sba → "aaaaa"なStringBuffer
 sbb → "bbbbb"なStringBuffer

で、f(sba, sbb)を呼び出すと、sb1、sb2はそれぞれsba、sbbを参照しているから、
 sba → "aaaaa"なStringBuffer ← sb1
 sbb → "bbbbb"なStringBuffer ← sb2
ここでsbaとsb1が参照している"aaaaa"なStringBufferはコピーとかではなく全く同じもので、"aaaaa"なStringBufferという実体はメモリ上にはただ一つしかないことに注意してください(もちろんsbbとsb2についても同じ)。

この状態で
 sb1 = new StringBuffer("ccccc");
が実行されると、
 sba → "aaaaa"なStringBuffer
 sbb → "bbbbb"なStringBuffer ← sb2
 sb1 → "ccccc"なStringBuffer
となって、sb1は"aaaaa"なStringBufferを参照するのをやめてしまいます。

次に、
 sb2.append("ddddd");
が実行されると、sb2はsbbと同じ"bbbbb"なStringBufferを参照しているので、実はabb.append("ddddd");を実行した場合と全く同じ変化が起きます。つまり、
 sba → "aaaaa"なStringBuffer
 sbb → "bbbbbddddd"なStringBuffer ← sb2
 sb1 → "ccccc"なStringBuffer
こうなるわけです。

そしてfが終了して再びmainに処理が戻ってきたとき、ローカルな変数sb1とsb2は破棄されて、以下のようになります。
 sba → "aaaaa"なStringBuffer
 sbb → "bbbbbddddd"なStringBuffer
ここで
 System.out.println("sba = " + sba);
 System.out.println("sbb = " + sbb);
が実行されれば当然
 sba = aaaaa
 sbb = bbbbbddddd
と出力されるわけです。
慣れるとどうってことありませんが、最初はわかりにくいかと思います。
わからなかったらまた聞いてください。
    • good
    • 0
この回答へのお礼

mach999さん丁寧で分かりやすい回答ありがとうございます。おかげで、スッキリ理解できました。本当に感謝します。

お礼日時:2004/09/02 22:18

メソッドの引数にあるオブジェクト(sb1やsb2)は元のオブジェクト(sbaやsbb)のメモリ上のアドレスがコピーされます。



sb2のようにそのアドレスのまま、実行すれば、sb2はsbbと同じオブジェクトのアドレスを指していますから、メソッドの中で実行した結果がメソッドを終了したあとも反映されています。
sb1のようにnewすると、sb1はその時点でnewされた別のオブジェクトを指します。そのため、sbaはもとのままです。

C言語のポインタと全く同じ動きです。
Javaにはポインタがないと言われますが、実際には「ポインタ演算」がないだけで、オブジェクトの扱いはポインタと同じです。
    • good
    • 0
この回答へのお礼

オブジェクトの扱いがポインタと同じとは知りませんでした。大事なことが分かってとても参考になりました。

お礼日時:2004/09/02 22:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!