この記事の内容は、Java の String は可変かどうかについてです。 (例の詳細な説明)は、必要な友人に参考にしていただけると幸いです。
Java の String クラスの設計が不変であることは誰もが知っています。String クラスのソース コードを見てみましょう。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0 // ... }
String クラスは Final 型であり、String を継承できないことがわかります。その値 value は文字配列のカプセル化、つまり char[] であり、その値は private Final として定義されます。これは、外部から変更できない、つまり不変であることを意味します。
次の例を見てください。
String str = "Python"; System.out.println(str); // Python str = "Java"; System.out.println(str); // Java str = str.substring(1); System.out.println(str); // ava
「str は Python から Java に変更されませんでしたか?」と疑問に思うかもしれません。そうするとsubstring方式でavaになるのでしょうか?
これは実は初心者の誤解です。上記の String の構造を見ると、文字列は文字配列で構成されていることがわかります。最初のリファレンスは「Python」です。後に「Java」に変更され、substring も Arrays.copyOfRange メソッドを使用して文字配列を再コピーし、新しい文字列を構築します。
つまり、ここの文字列は変数ではなく、文字列参照が変更されるだけです。
JDK のさまざまなバージョンの部分文字列の違いについては、この記事「注: jkd6、7、および 8 の文字列部分文字列メソッドの違い」を参照してください。また、各バージョンのソース コードを参照することもできます。部分文字列の。
上記の例は間違いなく不変ですが、次の例は恥ずかしいものです。
String str = "Hello Python"; System.out.println(str); // Hello Python Field field = String.class.getDeclaredField("value"); field.setAccessible(true); char[] value = (char[])field.get(str); value[6] = 'J'; value[7] = 'a'; value[8] = 'v'; value[9] = 'a'; value[10] = '!'; value[11] = '!'; System.out.println(str); // Hello Java!!
リフレクションを通じて、基になる文字配列の値を変更し、文字列の「不変性」を認識します。これは、Java の String クラスの要件に違反するため、推奨されません。設計原則により、セキュリティ上の問題が発生する可能性があります。
以上がJavaでは文字列は変更可能ですか? (詳細な例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。