字串緩衝池

2021-08-27 13:17:32 字數 1772 閱讀 9058

看到乙個關於字串緩衝池的討論

**)大家先來看看一段奇怪的程式:

public class teststring

}這個程式真是簡單啊!可是有什麼問題呢?

1. 來自 string 的憂慮

上面這段程式中,到底有幾個物件呢?

可能很多人脫口而出:兩個,s1 和 s2

為什麼?

string 是 final 類,它的值不可變。

看起來似乎很有道理,那麼來檢測一下吧,稍微改動一下程式

就可以看到結果了:

public class teststring

}呵呵,很多人都會說已經不止兩個物件了

編譯並執行程式,輸出:s1 == s2

啊!為什麼 s1 == s2 ?

== 分明是在說:s1 與 s2 引用同乙個 string 物件 -- "monday"!

2. 千變萬化的 string

再稍微改動一下程式,會有更奇怪的發現:

public class teststring

}我們將 s2 用 new 操作符建立

程式輸出:

s1 != s2

s1 equals s2

嗯,很明顯嘛

s1 s2分別引用了兩個"monday"string物件

可是為什麼兩段程式不一樣呢?

3. 在 string 的游泳池中游泳

哈哈,翻了翻書終於找到了答案:

原來,程式在執行的時候會建立乙個字串緩衝池

當使用 s2 = "monday" 這樣的表達是建立字串的時候,程式首先會

在這個string緩衝池中尋找相同值的物件,在第乙個程式中,s1先被

放到了池中,所以在s2被建立的時候,程式找到了具有相同值的 s1

將 s2 引用 s1 所引用的物件"monday"

第二段程式中,使用了 new 操作符,他明白的告訴程式:

「我要乙個新的!不要舊的!」與是乙個新的"monday"sting物件被創

建在記憶體中。他們的值相同,但是位置不同,乙個在池中游泳

乙個在岸邊休息。哎呀,真是資源浪費,明明是一樣的非要分開做什麼呢?

4. 繼續潛水

再次更改程式:

public class teststring

}這次加入:s2 = s2.intern();

補充:

當呼叫 intern 方法時,如果池已經包含乙個等於此 string 物件的字串(用 equals(object) 方法確定),則返回池中的字串。否則,將此 string 物件新增到池中,並返回此 string 物件的引用。 用intern可以提高堆記憶體的利用率。

哇!程式輸出:

s1 == s2

s1 equals s2

原來,程式新建了 s2 之後,又用intern()把他打翻在了池裡

哈哈,這次 s2 和 s1 有引用了同樣的物件了

我們成功的減少了記憶體的占用

5. == 與 equals() 的爭鬥

string 是個物件,要對比兩個不同的string物件的值是否相同

明顯的要用到 equals() 這個方法

可是如果程式裡面有那麼多的string物件,有那麼多次的要用到 equals ,

哦,天哪,真慢啊

更好的辦法:

把所有的string都intern()到緩衝池去吧

最好在用到new的時候就進行這個操作

string s2 = new string("monday").intern();

這樣大家都在水池裡泡著了 。

字串留用與字串池

1 關於字串操作對應用程式效能的影響 字串相等性檢查是應用程式常見的操作,於此同時,這也是一種嚴重損害效能的操作.執行序號 字串的二進位制 相等行檢查時,clr會進行以下操作 1 判斷字串的長度是否相等,不相等,比較結果直接返回false,如果相等,繼續下一步操作 2 比較字串的長度相等,clr會比...

字串常量池

string的不可變性。字串常量池是不會儲存相同內容的字串。xx stringtablesize設定stringtable的長度。jdk8最小值為1009 string的string pool是固定大小的hashtable 字串常量池在堆中。字串拼接操作 和 equals equals 對於obje...

字串常量池

string a hello string b hello string aa new string aa string bb new string bb 字串常量池在方法區中 其中 變數a jvm先到字串常量池中尋找如果沒有就在字串常量池中建立乙個字串hello,並且將該字串常量池的hello的記...