![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
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");
}
}
No.1ベストアンサー
- 回答日時:
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
と出力されるわけです。
慣れるとどうってことありませんが、最初はわかりにくいかと思います。
わからなかったらまた聞いてください。
No.2
- 回答日時:
メソッドの引数にあるオブジェクト(sb1やsb2)は元のオブジェクト(sbaやsbb)のメモリ上のアドレスがコピーされます。
sb2のようにそのアドレスのまま、実行すれば、sb2はsbbと同じオブジェクトのアドレスを指していますから、メソッドの中で実行した結果がメソッドを終了したあとも反映されています。
sb1のようにnewすると、sb1はその時点でnewされた別のオブジェクトを指します。そのため、sbaはもとのままです。
C言語のポインタと全く同じ動きです。
Javaにはポインタがないと言われますが、実際には「ポインタ演算」がないだけで、オブジェクトの扱いはポインタと同じです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- テレビ TVブースターの電源はTVの付近にある? 2 2022/09/28 15:12
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Java java final 1 2022/06/10 22:49
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- Java Java 配列<選挙> 4 2023/07/31 15:07
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Vba ListViewの行挿入に関して...
-
JSPでのArrayListの表示につい...
-
VBAでの[]
-
サーブレットコンテキストの意...
-
C#で親にイベントを投げる方法
-
エクセルVBA 画像を貼り付ける...
-
VB.netでメソッドからコントロ...
-
VB.NETでのnothing の意義について
-
Javaでブラウザ判定
-
エクセルVBA Property Let とメ...
-
servletからjspへオブジェクト...
-
getHeigth,getWidthについて
-
GridViewに行追加するには?
-
C#でのExcel操作について.(Ran...
-
Visual BasicでJavaアプレット...
-
SocketでXMLオブジェクトを送信...
-
Excel VBA 定数にオブジェクト...
-
String型からlong型への変換は...
-
WSHについて教えてください。
-
画像ファイルをリクエストパラ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAでの[]
-
VB.netでメソッドからコントロ...
-
サーブレットコンテキストの意...
-
servletからjspへオブジェクト...
-
エクセルVBA 画像を貼り付ける...
-
Vba ListViewの行挿入に関して...
-
VB.NETでのnothing の意義について
-
JSPでのArrayListの表示につい...
-
Excel VBA 定数にオブジェクト...
-
javaで、、、
-
C#のクラスで値渡しをする
-
String型からlong型への変換は...
-
getParameter()について
-
PrintFormを使用してのプリント
-
C#で親にイベントを投げる方法
-
Dispose()は、どんな時に使うの...
-
Javaでブラウザ判定
-
MessageBox.Show(Me,…の「Me」...
-
GridViewに行追加するには?
-
VB2005でADDとINSERTの違いは?
おすすめ情報