衆所周知:
Stirng是個不可變的類,因爲使用了final來修飾,如:
又有一個衆所周知:
就是 String的本質是一個char[] 數組。
所以爲了確保String真的不可變,那麼本質肯定不能變,於是乎這個char[]數組,如:
而且這個成員變量是沒有提供set和get方法。
看到這裏,其實可以知道的就是,如果這個value數組的元素被改變了,那麼String就是被改變了。
所以在String的源碼裏,諸多方法裏面都沒有涉及到直接去修改value[]的元素。
再度聚焦:
這個構造函數,一眼能看明白意思,就是通過傳遞一個char 數組,進行構造出一個新的String。
但是又細眼一看?
這裏使用到了Arrays的copyOf方法去實現深拷貝:
這樣做的原因大家都知道,就是重新開闢一波新的空間,這樣防止 在後續修改傳入的char value[] 裏的元素,導致String也跟着被修改(如果寫成 this.value=value)
霸王硬上弓:
那麼咱們就是要修改String,怎麼辦?
那肯定就是修改它的本質 char[] value的元素了。
咱們通過反射去修改String的成員變量,也就是這個本質 char數組,一起來看看:
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
String testStr = "JCccc";
System.out.println("一開始的testStr值爲 : " +testStr);
System.out.println(testStr.hashCode());
//反射機制,獲取獲取String裏面的的value字段
Field valueFieldOfString = String.class.getDeclaredField("value");
//設置value屬性的訪問權限爲true
valueFieldOfString.setAccessible(true);
//獲取s對象上的value屬性的值
char[] value = (char[]) valueFieldOfString.get(testStr);
//改變value數組中的元素
value[1] = 'A';
value[2] = 'a';
System.out.println("被操作之後的testStr爲 : " +testStr);
System.out.println(testStr.hashCode());
}
看一下效果:
好了,該篇就到此。