概述
(1)運(yùn)行時(shí)常量池屬于方法區(qū)的一塊內(nèi)存
(2)用于存放編譯期生成的各種字面量和符號(hào)引用迁霎,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池中存放。
根據(jù)jvm內(nèi)存區(qū)域分布实胸,我們知道
(1)java棧(虛擬機(jī)棧)是用于存儲(chǔ)局部變量表馋没,操作棧械蹋,動(dòng)態(tài)鏈接,方法出口等信息绸硕。(方法執(zhí)行的時(shí)候)
(2)堆:所有對(duì)象實(shí)例及數(shù)組都要在堆上分配內(nèi)存堂竟;
詳解
圖例:
image.png
如圖所示魂毁,定義a1和a2的時(shí)候,在堆中應(yīng)該創(chuàng)建兩個(gè)地址出嘹,分別用存放兩個(gè)abc席楚,因此我們用==判斷地址是否相等的時(shí)候應(yīng)該返回false;
String a1 = "abc";
String a2 = "abc";
System.out.println(a1==a2);
//true or false ?
運(yùn)行結(jié)果如下:bA.gif
我們發(fā)現(xiàn)運(yùn)行結(jié)果是true税稼,由此可知烦秩,abc有另外的一塊存儲(chǔ)位置;
如下圖娶聘,我們可以假象闻镶,有這樣的一塊結(jié)構(gòu)在方法區(qū),有一塊類似hashset的數(shù)據(jù)結(jié)構(gòu)丸升,創(chuàng)建一個(gè)字符創(chuàng)就會(huì)在常量池中創(chuàng)建一個(gè)铆农,hashset集合無序不重復(fù),在a1存入的時(shí)候狡耻,在常量池生成abc墩剖,a2進(jìn)來的時(shí)候,現(xiàn)在常量池中查找夷狰,是否存在abc岭皂,存在的話,直接指向沼头,不存在新建對(duì)象爷绘;
image.png
String a1 = "abc";
String a3 = new String("abc");
System.out.println(a1==a3);
//true or false ?
運(yùn)行結(jié)果如下:cc.gif
而直接new 創(chuàng)建對(duì)象,值一定是在堆內(nèi)存中进倍,
image.png
如上圖所示a3和a1并不是一塊內(nèi)存空間土至,因此返回的是false;
System.out.println(a1 == a3.intern());
//true or false
擴(kuò)展
intern()方法就是把a(bǔ)3的值取到猾昆,丟到常量池里面陶因,產(chǎn)生運(yùn)行時(shí)常量,這樣a3.intern()取到的值就是常量池中的值垂蜗,a1==a3 返回返回true楷扬;
直接內(nèi)存: