Java String 爲什麼不可變? 真的嗎?

衆所周知:

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());

    }

看一下效果:

 

 

好了,該篇就到此。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章