1

以下のリンクを参考にしました

Javaの文字列プールとは?

ガベージ コレクションと文字列

http://www.xyzws.com/Javafaq/what-is-string-literal-pool/3

Java の String プールに関する質問

まだ疑問があります 助けてください

            `public class StrPool
             { 
               public static void main(String[] args)
               { 
                String abc="hello";
                String abcd="hello";
                System.out.println(abc==abcd);
               }
             }
             `

上記の例では OP : true

したがって、両方のオブジェクトが同じ String オブジェクトから参照されていることを確認できます。それについては明らかです。

    `String abc="hello World";
     String abcd="hello";
     System.out.println(abc==abcd);`

これにより、出力が得られます:false

2つのStringオブジェクトが同じリテラルを持つ場合、Stringプールが実行されますか???

その場合、String プールに String の 2 つのオブジェクトが作成されますか??

2 番目の出力が false である理由 ???

私は String クラスが不変であることを読みました

abcabcd不変手段とは異なるオブジェクト参照を持っています

" 最初の String オブジェクトは JVM によって作成され、abc と abcd への 2 つの参照を与えます。

どうもありがとうございました........

4

4 に答える 4

2

2番目の出力は、文字列と異なるコンテンツ(テキスト)falseの両方です abcabcd

はい、あなたが言ったように、Stringクラスは不変です。つまり、その内容は変更されません。文字列テキストを変更した場合、 JVMはそれを変更する代わりに新しいスペースを割り当てます。

Stringその時点でテキストを含む新しい参照を作成すると、 JVMはそのテキストがプールに既に存在するかどうを確認し、そのテキストを参照する、プール内に 新しいテキストを作成します。

于 2012-08-01T09:29:06.247 に答える
1

最初のコードを考えてみましょう。

ステートメントの実行中String abc="hello"、JVMは次のことを行います。1。文字列型の参照abcを作成します。2.リテラル"hello"が文字列プールで使用可能かどうかを確認します。使用可能な場合は参照値をabcに割り当てます。そうでない場合は、文字列リテラル "hello"を作成し、参照をabcに割り当てて、文字列プールに追加します。

同じ手順が。に対して繰り返されString abcd="hello"ます。ここで、「hello」は文字列プールですでに使用可能であるため、同じものがabcdによって参照されます。

これらの同じ手順は、2番目のコードブロックでも実行されます(実際、このようなステートメントで文字列オブジェクトを作成するたびに)、リテラル「helloworld」と「hello」が異なる方法で作成され、それぞれの変数に割り当てられます。

これで、上記の2つのコードサンプルの出力の背後にある理由を推測できます。

文字列は不変です。つまり、文字列オブジェクトを変更することはできません。代わりに、JVMは新しい文字列オブジェクトを作成し(または文字列プールからフェッチし)、それを参照に割り当てます。例えば

   String varA = "hello"; -> 1

   String varB = "hello"; -> 2

   varA="world" -> 3

   varB ="world" -> 4

1行目で、JVMは文字列プールに文字列オブジェクト「hello」を作成し、その参照をvarAに割り当てます。2行目で、JVMは文字列プールにすでに存在する「hello」オブジェクトの参照をvarBに割り当てます。3行目で、JVMは新しいオブジェクト「world」を作成し、その参照をvarAに割り当てます。これで、文字列プールには「hello」と「world」の2つのオブジェクトが含まれるようになります。4行目で、JVMは文字列プールにすでに存在する「ワールド」オブジェクトの参照をvarBに割り当てます。文字列プールには、「hello」と「world」の2つのオブジェクトが引き続き含まれます。

したがって、基本的に、JVMはStringオブジェクトを変更せず、参照を変更しただけです。

お役に立てば幸いです。何か問題があればコメントしてください。

于 2012-08-01T09:42:05.307 に答える
1

2つのStringオブジェクトが同じリテラルを持つ場合、Stringプールが実行されますか???

--> そうではありません。リテラル文字列を定義すると、文字列プールが実行されます。とのようなリテラル文字列オブジェクトを作成String obj = "sometext"すると、 のような 2 番目のリテラルを作成しているString obj1 = "some Other Text"ときに、obj1 の内容が JVM によって "sometext" と比較されます。String str1 = "hello"と のように両方の内容が等しい場合String str2 = "hello"、オブジェクトは参照str1し、str2同じオブジェクト ("hello") を指します。

2 番目の出力が false である理由 ???

-->と が異なる文字列オブジェクトabcabcd指しているためです。

不変の意味: オブジェクトが作成されると、その内容を変更することはできません。

于 2012-08-01T09:43:38.910 に答える
1

Java は、 String.internを二重引用符で囲まれたリテラルに自動的に適用します。したがって、次のことが保証されます。

String foo1 = "foo";
String foo2 = "foo";
assert foo1 == foo2;

ただし、リテラル以外で構築された文字列の場合、これは保証されません。

String foo1 = "foo";
// contrived example, but imagine foo2 came from reading a file or similar
String foo2 = new String(new char[] { 'f', 'o', 'o' });

保証されていますfoo1.equals(foo2)が、必ずしもそうとは限りませんfoo1 == foo2。明示的に呼び出すことができますintern-それは保証されています-しかし、値の等価性を気にするときfoo1 == foo2.intern()に使用し、参照の等価性が本当に必要な場合にのみ == を使用する方が一般的に明確です。equals

于 2012-08-01T09:43:55.190 に答える