[解決済み】Javaにおける文字列の不変性
質問
次のような例を考えてみましょう。
String str = new String();
str = "Hello";
System.out.println(str); //Prints Hello
str = "Help!";
System.out.println(str); //Prints Help!
さて、Javaでは、Stringオブジェクトはイミュータブル(不変)です。では、どうして
str
には "Help!"という値を割り当てることができます。これは、Javaの文字列の不変性と矛盾していませんか?どなたか、不変性の正確な概念について説明していただけませんか?
編集する
OK。今、私はそれを得ているが、ちょうど1つのフォローアップの質問。次のコードはどうでしょう。
String str = "Mississippi";
System.out.println(str); // prints Mississippi
str = str.replace("i", "!");
System.out.println(str); // prints M!ss!ss!pp!
これは、2つのオブジェクトが再び作成され("Mississippi"と"M!ss!ss!pp!")、参照先の
str
の後に別のオブジェクトを指しています。
replace()
メソッドを使用しますか?
どのように解決するのですか?
str
はオブジェクトではなく、オブジェクトへの参照です。
"Hello"
と
"Help!"
は、2つの異なる
String
オブジェクトを作成します。このように
str
を指しています。
という文字列があります。を変更することができます。
を指す
しかし、それが
指す
.
たとえば、こんなコード。
String s1 = "Hello";
String s2 = s1;
// s1 and s2 now point at the same string - "Hello"
では、何もない
1
に対して、私たちができることは
s1
の値に影響を与えるような
s2
. これらは同じオブジェクト、つまり文字列
"Hello"
- しかし、このオブジェクトは不変であり、変更することはできません。
こんなことをしたら
s1 = "Help!";
System.out.println(s2); // still prints "Hello"
ここでは、オブジェクトの変異と、参照の変更の違いを見てみましょう。
s2
は、最初に設定したのと同じオブジェクトを指しています。
s1
を指すようにします。設定する
s1
から
"Help!"
を変更するだけです。
参照
一方
String
オブジェクトは変更されません。
文字列 は mutableであれば、このようなことが可能です。
String s1 = "Hello";
String s2 = s1;
s1.setCharAt(1, 'a'); // Fictional method that sets character at a given pos in string
System.out.println(s2); // Prints "Hallo"
OPの編集に対応するために編集しました。
を見ると String.replace(char,char) のソースコード (JDKのインストールディレクトリのsrc.zipにもあります。何かが本当にどう動くのか疑問に思ったら、いつでもそこを見るのがプロのコツです。) このコードがやっていることは、以下の通りです。
-
が1つ以上出現している場合
oldChar
が出現する現在の文字列のコピーを作成します。oldChar
に置き換えます。newChar
. -
もし
oldChar
が存在しない場合、現在の文字列を返します。
そうそう。
"Mississippi".replace('i', '!')
は、新しい
String
オブジェクトを作成します。この場合も、次のようになります。
String s1 = "Mississippi";
String s2 = s1;
s1 = s1.replace('i', '!');
System.out.println(s1); // Prints "M!ss!ss!pp!"
System.out.println(s2); // Prints "Mississippi"
System.out.println(s1 == s2); // Prints "false" as s1 and s2 are two different objects
を変更した場合、上記のコードがどうなるかを確認することが当面の宿題となります。
s1 = s1.replace('i', '!');
を
s1 = s1.replace('Q', '!');
:)
1 実はこれ は 文字列(および他の不変のオブジェクト)を変異させることができます。これはリフレクションを必要とし、とてもとても危険なので、実際にプログラムを破壊することに興味があるのでなければ、決して使ってはいけません。
関連
-
[解決済み] 未処理の例外タイプIOException」が表示されるのですが?
-
[解決済み] javaでAnnotation Inheritanceのようなものはあるのでしょうか?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み] JavaScriptで複数行の文字列を作成する
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ストリングビルダー.イコール Java
-
[解決済み] この配列の中の数字を入れ替えるには、何が足りないのでしょうか?ジャバ
-
[解決済み] javax.mail.MessagingException: SMTPホストに接続できませんでしたか?
-
[解決済み] 親から継承したメソッドの可視性を下げることができない [重複]。
-
[解決済み] ORA-01654: インデックスを拡張できません。
-
[解決済み] アクティビティに割り当てられない
-
[解決済み] Maven: assembly-pluginが全く実行されない
-
[解決済み] Spring ApplicationContext - リソースリーク: 'context' が閉じられない
-
[解決済み] ヘッドリカーシオンとテールリカーシオンの違い [重複]について
-
[解決済み】文字列は不変です。具体的にはどういうこと?[重複しています。]