亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java String如何被設計成不可變對象

發布時間:2022-01-05 11:47:41 來源:億速云 閱讀:135 作者:iii 欄目:大數據

這篇文章主要介紹“java String如何被設計成不可變對象”,在日常操作中,相信很多人在java String如何被設計成不可變對象問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java String如何被設計成不可變對象”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一、什么是不可變對象

從字面意思也能夠理解,也就是我們的創建的對象不可改變。那什么是不可變呢?為了實現創建的對象不可變,java語言要求我們需要遵守以下5條規則:

(1)類內部所有的字段都是final修飾的。

(2)類內部所有的字段都是私有的,也就是被private修飾。

(3)類不能夠被集成和拓展。

(4)類不能夠對外提供哪些能夠修改內部狀態的方法,setter方法也不行。

(5)類內部的字段如果是引用,也就是說可以指向可變對象,那我們程序員不能獲取這個引用。

正是由于我們的String類型遵循了上面5條規則,所以才說String對象是不可變的。想要去了解他還是看看String類型內部長什么樣子再來看上面5條規則吧。

二、String如何被設計成不可變對象的

1、疑惑一

在看之前,我們先給出一個疑惑問題,我們看下面的代碼,

public class Test2 {
    public static void main(String[] args) {
        String a="張三";
        System.out.println(a);
        a="李四";
        System.out.println(a);
    }
}
//output:
//張三
//李四
 

在文章一開始我們就說了,String對象是不可變的,這里a=張三,然后a=李四,這符合String的不可變性嘛?答案是當然符合。

java String如何被設計成不可變對象

從上面這張圖我們可以看到,在第一次String a="張三"的時候,在堆中創建了同一個對象“張三”。后來我們在執行a="李四"的時候再內存中又創建了一個對象“李四”。也就是說我們的a僅僅只是改變了引用a指向的地址而已。

2、源碼解釋疑惑

既然a指向的引用地址改變了,那么其String內部肯定有一個變量,能夠指向不同的實際對象,想要進一步弄清楚我們就進入其String的內部來看看。

我們在這里主要通過String類的源碼來分析,看一下Java語言是如何設計,能把String類型設計成不可變的。這里給出的是jdk1.8的一部分源碼。

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
    ......
}
 

上面最主要的是兩個字段:value和hash。我們在這里主要是看value數組,hash和主題無關所以這里不再講解了,我有專門的文章介紹hash。

我們的String對象其實在內部就是一個個字符然后存儲在這個value數組里面的。但是value對外沒有setValue的方法,所以整個String對象在外部看起來就是不可變的。我們畫一張圖解釋一下上面的疑惑

java String如何被設計成不可變對象

現在明白了吧,也就是說真正改變引用的是value,因為value也是一個數組引用。這也可以很方便的解釋下一個疑惑問題了。

3、疑惑二

既然我們的String是不可變的,好像內部還有很多substring, replace, replaceAll這些操作的方法。好像都是對String對象改變了,解釋起來也很簡單,我們每次的replace這些操作,其實就是在堆內存中創建了一個新的對象。然后我們的value指向不同的對象罷了。

面試的時候我們只是解釋上面的原因其實不是那么盡善盡美,想要更好的去加薪去裝逼,我們還需更進一步回答。

三、有什么辦法能夠改變String

既然有這個標題。那肯定就是有辦法的,別忘了我們的反射機制,在通常情況下,他可以做出一些違反語言設計原則的事情。這也是一個技巧,每當面試官問一些違反語言設計原則的問題,你就可以拿反射來反駁他。下面我們來看一下:

public class Test2 {
    public static void main(String[] args) {
        String str = "張三";
        System.out.println(str);
        try {
            //我們通過反射獲取內部的value字符數組
            Field field = String.class.getDeclaredField("value");
            field.setAccessible(true);
            char[] value;
            value = (char[]) field.get(str);
            //把字符串第一個字符變成王
            value[0] = '王';
            System.out.println(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//output:
//張三
//王三
 

我們可以通過反射來改變String。

現在我們知道它的原理以及用法,也知道可以通過反射來改變String,還有一個問題我們沒有弄清楚,面試的時候你也可以反問他,來進一步提升自己的逼格。

四、JAVA語言為什么把String類型設計成不可變

這里有幾個特點。

第一:在Java程序中String類型是使用最多的,這就牽扯到大量的增刪改查,每次增刪改差之前其實jvm需要檢查一下這個String對象的安全性,就是通過hashcode,當設計成不可變對象時候,就保證了每次增刪改查的hashcode的唯一性,也就可以放心的操作。

第二:網絡連接地址URL,文件路徑path通常情況下都是以String類型保存, 假若String不是固定不變的,將會引起各種安全隱患。就好比我們的密碼不能以String的類型保存,,如果你將密碼以明文的形式保存成字符串,那么它將一直留在內存中,直到垃圾收集器把它清除。而由于字符串被放在字符串緩沖池中以方便重復使用,所以它就可能在內存中被保留很長時間,而這將導致安全隱患

第三:字符串值是被保留在常量池中的,也就是說假若字符串對象允許改變,那么將會導致各種邏輯錯誤

到此,關于“java String如何被設計成不可變對象”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

买车| 遵义县| 阳曲县| 措美县| 青铜峡市| 眉山市| 璧山县| 德兴市| 和平区| 罗山县| 安图县| 祁阳县| 四子王旗| 梓潼县| 淳化县| 青冈县| 独山县| 石嘴山市| 五大连池市| 霍邱县| 江北区| 黄龙县| 水城县| 泾阳县| 灌阳县| 平南县| 衡阳市| 简阳市| 建始县| 鱼台县| 弥渡县| 射洪县| 逊克县| 新绛县| 通江县| 桦甸市| 民乐县| 乌鲁木齐市| 永靖县| 明光市| 岳阳县|