首頁 >Java >java教程 >Java中的String是否可變? (實例詳解)

Java中的String是否可變? (實例詳解)

不言
不言原創
2018-09-17 17:12:152284瀏覽

本篇文章帶給大家的內容是關於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 真的 "不可變 " 嗎?

來看下面這個例子。

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 的結構可以得知字串是由字元陣列構成的,str 只是一個引用而已,第一次引用了"Python" ,後面變成了"Java",而substring 也是用Arrays.copyOfRange 方法重新複製字元陣列建構了一個新的字串。

Java中的String是否可變? (實例詳解)

所以說,這裡的字串並不是可變,只是變更了字串引用。

關於 substring 在 JDK 各個版本的差異可以看這篇文章《注意:字符串substring方法在jkd6,7,8中的差異》,也可以去看 substring 的各個版本的源碼。

String 真的真的真的 "不可變 " 嗎?

上面的例子肯定是不可變的,下面這個就尷尬了。

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] = &#39;J&#39;;
value[7] = &#39;a&#39;;
value[8] = &#39;v&#39;;
value[9] = &#39;a&#39;;
value[10] = &#39;!&#39;;
value[11] = &#39;!&#39;;
System.out.println(str); // Hello Java!!

透過反射,我們改變了底層的字元陣列的值,實現了字串的「不可變」 性,這是一種騷操作,不建議這麼使用,違反了Java 對String 類別的不可變設計原則,會造成一些安全問題。

以上是Java中的String是否可變? (實例詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn