[解決済み】文字列は不変です。具体的にはどういうこと?[重複しています。]
質問内容
イミュータブルなStringについて、次のようなコードを書いてみました。
public class ImmutableStrings {
public static void main(String[] args) {
testmethod();
}
private static void testmethod() {
String a = "a";
System.out.println("a 1-->" + a);
a = "ty";
System.out.println("a 2-->" + a);
}
}
出力します。
a 1-->a
a 2-->ty
ここでは、変数
a
が変更されました(一方、多くの人は、immutableオブジェクトの内容は変更できないと言います)。しかし、次のような言い方は正確には何を意味するのでしょうか?
String
は不変である
? このトピックを明確にしていただけませんか?
ソース https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
解決方法は?
の大騒ぎで先に進む前に
不変性
について見てみましょう。
String
クラスとその機能について、結論を出す前に少し説明します。
このように
String
が動作します。
String str = "knowledge";
これは、いつものように、以下を含む文字列が作成されます。
"knowledge"
を参照し、それに
str
. 簡単でしょう?では、さらにいくつかの関数を実行してみましょう。
String s = str; // assigns a new reference to the same string "knowledge"
以下の文がどのように機能するか見てみましょう。
str = str.concat(" base");
これは文字列を追加します
" base"
に
str
. しかし、ちょっと待ってください、なぜこんなことが可能なのでしょうか?
String
オブジェクトは不変なのでしょうか?驚いたことに、そうなのです。
上記のステートメントが実行されると、VMはその値を
String str
すなわち
"knowledge"
を追加し、さらに
" base"
という値が得られます。
"knowledge base"
. ここで
String
は不変なので、VM はこの値を
str
であるため、新しい
String
オブジェクトを作成し、そのオブジェクトに値
"knowledge base"
という参照を与える。
str
.
ここで重要な点は、このように
String
オブジェクトはイミュータブルです。
その参照変数はそうではありません。
そのため、上記の例では、参照先が新たに形成された
String
オブジェクトを作成します。
上の例では、この時点で2つの
String
オブジェクトを作成しました。
"knowledge"
で指される
s
と、2つ目の
"knowledge base"
で指される
str
. しかし、厳密には、3つの
String
オブジェクトで、3つ目はリテラルの
"base"
の中に
concat
ステートメントを使用します。
文字列とメモリ使用量に関する重要な事実
もし、別の参照がなかったらどうなるか
s
から
"knowledge"
? を失うことになる。
String
. しかし、それはまだ存在していたはずですが、参照がないため失われたとみなされます。
もう一つ、次の例を見てください。
String s1 = "java";
s1.concat(" rules");
System.out.println("s1 refers to "+s1); // Yes, s1 still refers to "java"
何が起きているのか
-
最初の行はとても簡単で、新しい
String
"java"
を参照しs1
を追加してください。 -
次に、VM は別の新しい
String
"java rules"
しかし、何も を参照しています。そこで、2番目のString
は瞬時に失われる。到達できないのです となります。
参照変数
s1
はまだ元の
String
"java"
.
ほとんどすべてのメソッドは
String
オブジェクトを変更するために、新しい
String
オブジェクトを作成します。では、これらの
String
オブジェクトはどこに行くのでしょうか?まあね。
プログラミング言語の重要な目標の1つは、メモリを効率的に使用することです。
アプリケーションが大きくなると
というのはよくあることです。
String
リテラルはメモリの大きな領域を占め、冗長性をもたらすことさえあります。
そこで、Javaをより効率的にするために
JVMは、quot;String constant pool"と呼ばれる特別なメモリ領域を確保します。
コンパイラは
String
というリテラルがある場合、それは
String
をプール内に置く。一致するものが見つかった場合、新しいリテラルへの参照は、既存の
String
となり、新しい
String
オブジェクトが作成されます。既存の
String
は単に参照が1つ増えただけです。ここで
String
オブジェクトは不変である。
において
String
定数プールに
String
オブジェクトは、1つまたは複数の参照を持つ可能性があります。
複数の参照先が同じ
String
を知らないうちに、そのリファレンスの1つがその
String
の値を指定します。そのため
String
オブジェクトはイミュータブルです。
さて、今ならこう言えるでしょう。
の機能を上書きしてしまったらどうなるのでしょうか?
String
クラスはどうでしょうか?
そのため
は
String
クラスがマークされています。
final
のように、誰もそのメソッドの動作をオーバーライドできないようにします。
関連
-
[解決済み] getContentPane()は具体的に何をするのですか?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] JavaBeanとは何ですか?
-
[解決済み】JavaScriptで文字列の出現箇所をすべて置換する方法
最新
-
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でFileFilterを作るには?
-
[解決済み] java.util.concurrent.ExecutionException 例外をどのように処理しますか?
-
[解決済み] Java UnknownFormatConversionException
-
[解決済み] 要素 'beans' の宣言が見つかりません。
-
[解決済み] JavaにおけるMouseListenerとMouseAdapterの違いについて
-
[解決済み] Apache Camelのログに簡単なテキストを記録する
-
[解決済み] javaでAnnotation Inheritanceのようなものはあるのでしょうか?
-
[解決済み] Javaにおけるシンボリック参照
-
[解決済み] java swingアプリケーションでJCEがプロバイダBCを認証できない
-
[解決済み】Javaにおける文字列の不変性