字符串常量池在堆中還是方法區(qū) 字符串常量池到底存放的是字符串引用還是字符串對象?
字符串常量池到底存放的是字符串引用還是字符串對象?你看看String源碼就明白了,是對象!s="123"寫這句話的時候,會在常量池先找有沒有123這個字符串對象如果沒有,他就開始抽取,1,2,3然后拼
字符串常量池到底存放的是字符串引用還是字符串對象?
你看看String源碼就明白了,是對象!
s="123"
寫這句話的時候,會在常量池先找有沒有123這個字符串對象如果沒有,他就開始抽取,1,2,3
然后拼接成一個對象即:"123"
假如后面又來一個也需要這個對象,比如說s1="123"
這個時候在操作s1的時候還是先去常量池找有沒有這個對象,如果有,直接把地址拿過來,因為常量池數(shù)據(jù)為共享的,
假如這個時候s1="1234"那么常量池是沒有的,就會重新抽取,1,2,3,4,然后重新拼接成一個新的對象放在常量池!
String源碼里面有一個私有變量一個字符類型的數(shù)組,他就是用來抽取這些單個字符,然后拼接成
一個字符串對象!
字符串常量池是在方法區(qū)中還是在獨立的區(qū)域中?
String str = "nihao" 程序開始執(zhí)行這句代碼,肯定是要創(chuàng)建一個對象的, 只是這個對象創(chuàng)建后就是一個常量,不可以更改, 并且這個對象是放在串池里面的,也就是你說的那個常量池
如果我后面在寫一句代碼: String other = "nihao"
str和other這2個引用的地址就是一樣的, 因為str和other的聲明方式是一樣的, 都是在串池, str的對象創(chuàng)建時,串池中沒有"nihao"這個常量,就創(chuàng)建一個. other對象創(chuàng)建時,發(fā)現(xiàn)串池中已經(jīng)有了"nihao"這個常量, 就直接拿過來用就是了
String a1 = new String("nihao")
String b1 = new String("nihao")
但是如果我們通過上面的方式直接new String() 那個a1和b1這2個引用的對象就不是在串池中了,而是在堆中, 但是new String() 的參數(shù)"nihao"也是一個字符串啊, 這個字符串從哪里來呢?如果我們吧代碼拆分一下就明白了:
String para = "nihao"
String a1 = new String(para)
就會發(fā)現(xiàn)String a1 = new String("nihao") 這一句代碼實際上創(chuàng)建了2個對象, 一個是String對象,存放在堆中, 一個是字符串常量對象,存放在串池中
字符常量池是什么意思?
可以理解為內(nèi)存里面專門為string類型變量開辟的一片區(qū)域譬如String a = "abc" 當(dāng)你定義這樣一個變量的時候,java此時先會去常量池尋找有沒有"abc"這樣的字符串,如果有,直接把內(nèi)存地址交給a, 否則就生成一個"abc"的字符串當(dāng)下一個String b = "abc"的時候,發(fā)現(xiàn)常量池已經(jīng)有"abc"了,此時JVM不會再次生成"abc",而是直接交給"abc"引用給b, 所以此時你會發(fā)現(xiàn)a == b
Java中的字符串常量池與Java中的堆和棧的區(qū)別?
java常量池不在堆中也不在棧中,是獨立的內(nèi)存空間管理。
1. 棧:存放基本類型的變量數(shù)據(jù)和對象的引用,但對象本身不存放在棧中,而是存放在堆(new 出來的對象)或者常量池中(字符串常量對象存放在常量池中。)
2. 堆:存放所有new出來的對象。
3. 常量池:存放字符串常量和基本類型常量(public static final)。
對于字符串:其對象的引用都是存儲在棧中的,如果是編譯期已經(jīng)創(chuàng)建好(直接用雙引號定義的)的就存儲在常量池中,如果是運(yùn)行期(new出來的)才能確定的就存儲在堆中。對于equals相等的字符串,在常量池中永遠(yuǎn)只有一份,在堆中有多份。