- ベストアンサー
Stringクラスの文字列の内容
こんにちわ。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=742689 に似たような質問がございましたが・・・ 関連書籍やサイトのいずれを見ても、 「Stringクラスは文字列の内容を変更することは出来ない」 と書いていますが・・・ String str1; String str2; str1="こんにちわ"; str2="さようなら"; str1=str1+str2; System.out.println(str1); とコーディングすると、何事もなく、 「こんにちわさようなら」 と出力されます。 そうなると、StringBufferクラスのappendメソッドをわざわざ使用しなくてもよくなるのですが、 これは、どのように解釈すればよいのかご存知の方がおりましたら、ぜひ、教えてください。 以上、宜しくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
str1 のような変数は、参照型と言って、自身がその内容なのではなくて、オブジェクトを参照しています。 >str1=str1+str2; の場合、str1+str2 で新しくString オブジェクトが作成されて、それに対する参照に付け替えられます。 StringBufferクラスのappendメソッド を使うかどうかは、 領域を再利用するかどうかで検討すればいいでしょう。 (String を使った場合は新しく作っては古い領域が捨てられるので、追加するような場合に速度的に不利です)
その他の回答 (2)
- arakororin
- ベストアンサー率39% (80/205)
StringはJavaのクラスの中で明示的にオブジェクトを作成しなくてもよい極めて特殊なクラスです。ですので非常に理解しにくいと思います。 str1="こんにちわ"; str2="さようなら"; str1=str1+str2; は str1 = "こんにちわ"; str2 = "さようなら"; str1 = (new StringBuffer(str1)).append(str2).toString(); と言う記述をしなければらならないところを、特別に省略形を許しているのです。こんな記述を許すオブジェクトはStringのみです。 上記の2表現のどちらにせよ、イコール演算子を使用してオブジェクトを代入しなおしています。新しくオブジェクトを生成してそのオブジェクトを代入しているのです。 またStringの持つどのメソッドを実行しても、その内部表現そのものを変更することは不可能で、戻り値として返された値を代入しなければいけません。 例えば str1.trim(); と記述しても内容は不変であり str1 = str1.trim(); としなければならないのです。 一方StringBufferは自分の持つメソッドを実行することにより、内部表現を変更しています。代入はいらないのです。
お礼
回答ありがとうございました。 確かに理解しにくいですね。 単に「変更できない」と覚えるのではなく、 内部表現を変更できるのがStringBuffer、 内部表現を変更できないのがString、 と理解するのが、いいのですね。 ・・・本当に理解しにくいです。 皆さんのおかげで、少し、理解が深まりました。 ありがとうございました。
この質問の回答にもあるように、 Stringの内部でもっている文字列オブジェクトが可変であるということです。 str1=str1+str2; とした場合でも、 str1とstr2を結合した新しい"こんにちわさようなら"という新しいStringインスタンスが生成されます。 もともとあったstr1のインスタンスの内容が変わるのではなく、 あくまでもstr1という変数ののインスタンスを指す参照先が変わるだけです。 で、文字列の編集ですが、+を使って編集したとしても、 これはコンパイラによってStringBufferを使ったコードに最適化されるそうです。 一般的に、+を使ったStringの連結はパフォーマンスが遅いと言われてます。 そのため、一般的にはStringBufferを使うことを推奨されていますが、最近のJDKバージョン1.4以降は、昔ほどのパフォーマンスの違いはそれほどありません。
お礼
回答ありがとうございました。 つまり、正式にはやはりStringBufferなんですね。 「この場合、もともとあったstr1のインスタンスの内容は、どこに行っちゃうのだろう?」 と考えると、なんだか、狐につままれたような気分ですが、なんとなく、わかりました。 ありがとうございました。
お礼
新しく作っては古い領域が捨てられるから、パフォーマンスに影響が出るんですね。 箱の中身を入れ替えるのではなくて、箱を次々と作成しては破棄するようなものだと言うことですよね? 回答、ありがとうございました。 勉強になりました。