String地址

已經過測試,真的誒-O-

JVM內存區域裏面有一塊常量池,關於常量池的分配

  1. JDK6的版本,常量池在持久代PermGen中分配
  2. JDK7的版本,常量池在堆Heap中分配

字符串是存儲在常量池中的,有兩種類型的字符串數據會存儲在常量池中:

  1. 編譯期就可以確定的字符串,即使用""引起來的字符串,比如String a = "123"String b = "1" + B.getStringDataFromDB() + "2" + C.getStringDataFromDB()、這裏的"123"、"1"、"2"都是編譯期間就可以確定的字符串,因此會放入常量池,而B.getStringDataFromDB()、C.getStringDataFromDB()這兩個數據由於編譯期間無法確定,因此它們是在堆上進行分配的
  2. 使用String的intern()方法操作的字符串,比如String b = B.getStringDataFromDB().intern(),儘管B.getStringDataFromDB()方法拿到的字符串是在堆上分配的,但是由於後面加入了intern(),因此B.getStringDataFromDB()方法的結果,會寫入常量池中

常量池中的String數據有一個特點:每次取數據的時候,如果常量池中有,直接拿常量池中的數據;如果常量池中沒有,將數據寫入常量池中並返回常量池中的數據

因此回到我們之前的場景,使用StringBuilder拼接字符串每次返回一個new的對象,但是使用intern()方法則不一樣:

"XXX-192.168.1.1"這個字符串儘管是使用StringBuilder的toString()方法創建的,但是由於使用了intern()方法,因此第一條線程發現常量池中沒有"XXX-192.168.1.1",就往常量池中放了一個
"XXX-192.168.1.1",後面的線程發現常量池中有"XXX-192.168.1.1",就直接取常量池中的"XXX-192.168.1.1"。

因此不管多少條線程,只要取"XXX-192.168.1.1",取出的一定是同一個對象,就是常量池中的"XXX-192.168.1.1"

這一切,都是String的intern()方法的作用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章