■問題
次のプログラムを実行すると、出力結果はどのようになりますか。1つ選択してください。
http://d.hatena.ne.jp/motoi20/20081210
■解説
正解は選択肢Aです。func(s)では、変数sが参照しているStringオブジェクトを「func(Stirng s)」の引数sに渡しています。func()メソッドの処理で「s+"Hello"」という処理をしたとき、内部では暗黙的に新しいStringオブジェクトが生成されます(変数sに文字列を追加しているわけではありません。)func()メソッドの呼び出しが「s=func(s)」となっていた場合、main()メソッド内の変数sが新しくできたオブジェクトを参照するため、結果の出力は「JavaHello」になりますが、「func(s)」の呼び出しでは戻り値を再代入していないため、変数sは文字列「Java」を保持したオブジェクトを参照します。Stringクラスは読み取り専用オブジェクトであることに注意しましょう。
■疑問
1)オブジェクトを作成は、「new」を使いますね?暗黙的に生成されるのは、どういう場合でしょうか?
2)読み取り専用オブジェクトだからStringクラスには代入できないということでしょうか?
1) オブジェクトを作成は、「new」を使いますね?
http://www.y-adagio.com/public/standards/tr_javalang/3.doc.htm#1...
3.10.5 文字列リテラルによると
> 文字列リテラルは,クラス Stringのインスタンスへの参照とする。
とありあます。(インスタンスへの参照とはほぼオブジェクトの生成です)
つまりJavaでは
String str = "Hello";は
String str = new String("Hello").intern();のと等価なのでnewはしています。
2) 読み取り専用オブジェクトだからStringクラスには代入できないということでしょうか?
Javaの場合、オブジェクトはインスタンスへの参照です。
String str = "Hello";
str = "Java";
が行われた場合、
1. 文字列リテラル"Hello"が生成される
2. 上記1.の参照がstrに代入される
3. 文字列リテラル"Java"が生成される
4. 上記3.の参照がstrに代入される
# この時点で文字列リテラル"Hello"が誰からも参照されなくなっている場合、ガベージコレクタの対象となる。
Stringクラスは確かにメンバ変数を操作するようなメソッドは提供されていませんが
それは読み取り専用クラスであるかどうかは微妙なところです。
丁寧な回答をありがとうございます。「ガベージコレクタの対象になる」というところまで解説していただき、非常に理解が深まりました。
読み取り専用クラスについての判断についてはおいておきます。確かにメンバ変数を操作するようなメソッドは提供されていませんね。ありがとうございました。