これは、上記の回答ですでに述べた2つの理由を概説する素晴らしい記事です。
- セキュリティ:システムは、読み取り専用情報の機密ビットが変更されることを心配せずに配布できます
- パフォーマンス:不変データは、スレッドセーフにするために非常に役立ちます。
そして、これはおそらくその記事で最も詳細なコメントです。これは、Javaの文字列プールとセキュリティの問題に関係しています。文字列プールに入れるものを決定する方法についてです。文字のシーケンスが同じである場合、両方の文字列が等しいと仮定すると、誰が最初にそこに到達するか、およびそれに伴ってセキュリティの問題に関する競合状態が発生します。そうでない場合、文字列プールには冗長な文字列が含まれるため、そもそもそれを使用する利点が失われます。自分で読んでくださいね。
Stringを拡張すると、equalsとinternで大混乱が発生します。JavaDocは次と等しいと言います:
この文字列を指定されたオブジェクトと比較します。引数がnullではなく、このオブジェクトと同じ文字シーケンスを表すStringオブジェクトである場合にのみ、結果はtrueになります。
java.lang.String最終ではないと仮定すると、a SafeStringはと等しい可能性がStringあり、その逆も同様です。同じ文字シーケンスを表すためです。
あなたが適用される場合、何が起こるかinternにSafeString希望- SafeStringJVMの文字列プールに入りますか?ClassLoaderそして、すべてはオブジェクトSafeStringその後、JVMの寿命のために所定の位置にロックになるだろうに保持された参照を。あなたは文字の並びインターンへの最初の可能性が誰についての競合状態を取得したい-多分あなたはSafeString、多分勝つStringか、あるいはSafeString別のクラスローダ(したがって、異なるクラス)によってロードされました。
あなたがプールへの競争に勝った場合、これは真のシングルトンであり、人々はリフレクションとを通じてあなたの環境全体(サンドボックス)にアクセスできますsecretKey.intern().getClass().getClassLoader()。
または、JVMは、具象文字列オブジェクトのみ(サブクラスなし)がプールに追加されたことを確認することにより、このホールをブロックできます。
equalsがSafeString!=のように実装されている場合String、SafeString.intern!= String.internでありSafeString、プールに追加する必要があります。プールは、その後のプールになる<Class, String>代わりに<String>、あなたがプールを入力する必要があると思いますすべてが新鮮クラスローダーになります。