設計中にJavaデザイナーが実際に何を考えていたのかわからない String
わかりませんが、これらの理由は、文字列の不変性から得られる利点に基づいてのみ結論を出すことができます。
1.文字列定数プールの存在
文字列が文字列定数プールに格納される理由で説明したように、すべてのアプリケーションは多すぎる文字列オブジェクトを作成し、JVMが最初に大量の文字列オブジェクトを作成してからガベージコレクションを実行しないようにします。JVMは、すべての文字列オブジェクトを文字列定数プールと呼ばれる別のメモリ領域に格納し、そのキャッシュされたプールからオブジェクトを再利用します。
文字列リテラルを作成するたびに、JVMはそのリテラルが定数プールにすでに存在するかどうかを最初に確認し、存在する場合は、新しい参照がSCP内の同じオブジェクトをポイントし始めます。
String a = "Naresh";
String b = "Naresh";
String c = "Naresh";
上記の例では、値を持つ文字列オブジェクトはNaresh
一度だけSCPに作成されますと、すべての参照a
、b
、c
同じオブジェクトを指しますが、どのような場合、我々はの変化作ってみるa
などをa.replace("a", "")
。
理想的にa
は、価値Nresh
がb
あるc
べきですが、エンドユーザーとしてa
のみ変更を行うため、変更しないでおく必要があります。そして、私たちは知っているa
、b
、c
我々は変化をするので、もしすべてが同じオブジェクトを指していますa
、他の人も変更を反映すべきです。
しかし、文字列の不変性はこのシナリオから私たちを救い、文字列オブジェクトの不変性のために文字列オブジェクトNaresh
は決して変更されません。したがってa
、文字列オブジェクトを変更するのではなく変更を加えると、Naresh
JVMは新しいオブジェクトを作成し、それに割り当ててからa
、そのオブジェクトを変更します。
したがって、文字列プールは文字列の不変性のためにのみ可能であり、文字列が不変でなければ、文字列オブジェクトをキャッシュして再利用することは、変数が値を変更し、他の文字列を破損する可能性がないためです。
そして、それがJVMによって特別に処理され、特別なメモリ領域が与えられている理由です。
2.スレッドセーフティ
複数のスレッドがオブジェクトを操作している場合、オブジェクトはスレッドセーフと呼ばれますが、その状態を破壊することはできず、オブジェクトはいつでもすべてのスレッドに対して同じ状態を保持します。
私たちは不変オブジェクトを作成した後は誰も変更できないため、デフォルトではすべての不変オブジェクトがスレッドセーフになります。同期メソッドの作成など、スレッドセーフ対策を適用する必要はありません。
したがって、その不変の性質により、文字列オブジェクトは複数のスレッドで共有でき、多くのスレッドによって操作されている場合でも、その値は変更されません。
3.セキュリティ
すべてのアプリケーションで、ユーザーのユーザー名\パスワード、接続URLなどのいくつかのシークレットを渡す必要があります。通常、この情報はすべて文字列オブジェクトとして渡されます。
ここで、Stringが本質的に不変ではなかった場合、これらの値が変更される可能性があるため、アプリケーションに深刻なセキュリティ上の脅威を引き起こすと想定します。変数参照にアクセスできます。
4.クラスローディング
「例を使用したJavaでのリフレクションによるオブジェクトの作成」で説明したように、Class.forName("class_name")
メソッドをしてクラスをメモリにロードし、他のメソッドを呼び出してそれを行うことができます。また、JVMでもこれらのメソッドを使用してクラスをロードします。
しかし、これらのすべてのメソッドがクラス名を文字列オブジェクトとして受け入れることがはっきりとわかる場合は、Javaクラスの読み込みで文字列が使用され、不変性によって、によって正しいクラスが読み込まれるというセキュリティが提供されClassLoader
ます。
Stringが不変ではなく、ロードjava.lang.Object
を試みてorg.theft.OurObject
、その間に変更され、すべてのオブジェクトが、誰かが不要なことに使用できる動作を持っているとします。
5. HashCodeキャッシング
オブジェクトに対してハッシュ関連の操作を実行する場合は、hashCode()
メソッドをオーバーライドし、オブジェクトの状態を使用して正確なハッシュコードを生成する必要があります。オブジェクトの状態が変化している場合、つまり、そのハッシュコードも変化するはずです。
Stringは不変なので、1つの文字列オブジェクトが保持している値は決して変更されません。つまり、そのハッシュコードも変更されず、Stringクラスはオブジェクトの作成中にハッシュコードをキャッシュする機会が与えられます。
はい、文字列オブジェクトはオブジェクトの作成時にハッシュコードをキャッシュします。これにより、ハッシュコードを再計算する必要がなくなり、時間を節約できるため、関連する操作をハッシュするのに最適な候補になります。これが、文字列が主にHashMap
キーとして使用される理由です。
JavaでStringが不変で最終的な理由についての詳細を読んでください。