理由は、String
が不変であるためです。新しいインスタンスを作成せずに変更することはできません。したがって、マッチする文字列に対して可能な限り同じインスタンスを使用することは安全です。 Strings are constant; their values cannot be changed after they are created.
どのように配列は別の話です。配列を変更することができます。新しい値をフィールドの1つに代入するだけです。
s1[0] = "testString3"
コンパイラはatomatically両方の配列を変更しますs1
とs2
のための同じインスタンスを使用する場合。それはおそらくあなたがしたいことではないでしょう。それが配列がインターンされていない理由です。
コンパイラによっては文字列の数に制限があり、コンパイラは文字列の数や文字列の長さに応じていくつかの文字列を使用しないことがあります。内部文字列テーブルはJVMオプション+XX:StringTableSize=n
によって制御され、内部文字列を格納するために使用される文字列テーブルのサイズを決定します。
いつ文字列を比較するかは、equals関数を使用する方が良いです。ほとんどの実装では、より高価なチェックを実行する前に、まず参照平等がチェックされます。
EDIT:
だから、実際にインターン文字列のストレージがいっぱい育つというのが私の主張は間違っているようです。 String.intern()
メソッドのドキュメントは、この関数が文字列が一意の文字列のプールに追加されることを確認します。このプールがいっぱいになる方法がないことを意味します。 @Holgerは、内部実装がある種の構造のようなハッシュマップを使用していると書いています。これはその主張を支持する。
したがって、JVMは、JLS §3.10.5に基づいて、インターンされたハッシュテーブル内のすべての定数文字列を格納します。
文字列リテラルは、常にクラスStringの同じインスタンスを参照します。これは、文字列リテラルまたはより一般的には、定数式の値である文字列が、String.internメソッドを使用して一意のインスタンスを共有するように「中止」されているためです。
文字列クラスのメソッドequals
にも慣れていて、文字列が等しいかどうかをチェックします。この方法は、文字列が同じ参照であり、その場合には非常に高速であり、より高価な長さおよび文字チェックを行う前に完了するという事実を利用する。常にこのメソッドを使用する方が良いです。文字列の扱い方は、Javaの将来のバージョンで変更される場合もあれば変更されない場合もあります。 equals
メソッドを使用すると安全です。
インターンは、 'String'のためだけです。 –
Javaエコシステムの** any **その他のタイプについて、その質問をすることができます。 –
配列は不変ではありません。それらを自動的にインターンさせることは、大きな問題になるでしょう。 – khelwood