0

この記事ScjpTipLine-StringsLiterallyによると、次のようないくつかの例をコーディングしていました。

public static void main(String[] args) {
   String literalString1 = "someString";
   String literalString2 = "someString";
   String string1 = new String("someString");
   System.out.println(literalString1 == literalString2);
   System.out.println(literalString1 == string1);
   try {
       Field stringValue = String.class.getDeclaredField("value");
       stringValue.setAccessible(true);
       char[] charValue = "someString".toCharArray();
       Arrays.fill(charValue, 'a');
       stringValue.set(literalString1, charValue);
   } catch (Exception e) {}

   System.out.println(literalString1);
   System.out.println(literalString2);
   System.out.println(string1);
}

出力は期待通りです:

true
false
aaaaaaaaaa
aaaaaaaaaa
someString

ただし、上記のコードを少し変更すると、行が置き換えられます

char[] charValue = "someString".toCharArray();

char[] charValue = (char[]) stringValue.get(literalString1);

あなたが得る

true
false
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa

new String("someString");以来の予期しない出力です。JVM は、文字列リテラル プールのliteralString1literalString2を使用するのではなく、実行時にヒープに新しい String オブジェクトを作成する必要があります。

前もって感謝します

4

1 に答える 1

1

これは、新しいString( "someString");以降の予期しない出力です。JVMは、実行時にヒープ上に新しいStringオブジェクトを作成する必要があります

はい、新しいStringオブジェクトを作成する必要があります。

ただし、Stringオブジェクトは通常、いくつかのフィールドを持つ単なるヘッダーであり、バッキング配列へのポインターです。そして、JVMはそのバッキング配列を自由に再利用できます。

文字列は不変であると想定されています。その不変性に違反するために面倒なことをした場合、文字列がどのように動作するかについての保証はありません。

于 2010-12-06T23:22:05.007 に答える