public class test {
public static void main(String[] args) {
objPoolTest();
}
public static void objPoolTest() {
int i = 40;
int i0 = 40;
Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);
Double d1=1.0;
Double d2=1.0;
System.out.println("i=i0\t" + (i == i0));
System.out.println("i1=i2\t" + (i1 == i2));
System.out.println("i1=i2+i3\t" + (i1 == i2 + i3));
System.out.println("i4=i5\t" + (i4 == i5));
System.out.println("i4=i5+i6\t" + (i4 == i5 + i6));
System.out.println("d1=d2\t" + (d1==d2));
System.out.println();
}
}
結(jié)果:
i=i0 true
i1=i2 true
i1=i2+i3 true
i4=i5 false
i4=i5+i6 true
d1=d2 false
結(jié)果分析:
1.i和i0均是普通類型(int)的變量涩盾,所以數(shù)據(jù)直接存儲(chǔ)在棧中州泊,而棧有一個(gè)很重要的特性:棧中的數(shù)據(jù)可以共享。當(dāng)我們定義了int i = 40;窟勃,再定義int i0 = 40;這時(shí)候會(huì)自動(dòng)檢查棧中是否有40這個(gè)數(shù)據(jù)祖乳,如果有,i0會(huì)直接指向i的40秉氧,不會(huì)再添加一個(gè)新的40眷昆。
2.i1和i2均是引用類型,在棧中存儲(chǔ)指針汁咏,因?yàn)镮nteger是包裝類亚斋。由于Integer包裝類實(shí)現(xiàn)了常量池技術(shù),因此i1攘滩、i2的40均是從常量池中獲取的帅刊,均指向同一個(gè)地址,因此i1=12轰驳。
3.很明顯這是一個(gè)加法運(yùn)算厚掷,Java的數(shù)學(xué)運(yùn)算都是在棧中進(jìn)行的弟灼,Java會(huì)自動(dòng)對(duì)i1、i2進(jìn)行拆箱操作轉(zhuǎn)化成整型冒黑,因此i1在數(shù)值上等于i2+i3田绑。
4.i4和i5均是引用類型,在棧中存儲(chǔ)指針抡爹,因?yàn)镮nteger是包裝類掩驱。但是由于他們各自都是new出來(lái)的,因此不再?gòu)某A砍貙ふ覕?shù)據(jù)冬竟,而是從堆中各自new一個(gè)對(duì)象欧穴,然后各自保存指向?qū)ο蟮闹羔槪詉4和i5不相等泵殴,因?yàn)樗麄兯嬷羔槻煌塘保赶驅(qū)ο蟛煌?/p>
5.這也是一個(gè)加法運(yùn)算,和3同理笑诅。
6.d1和d2均是引用類型调缨,在棧中存儲(chǔ)指針,因?yàn)镈ouble是包裝類吆你。但Double包裝類沒(méi)有實(shí)現(xiàn)常量池技術(shù)弦叶,因此Doubled1=1.0;相當(dāng)于Double d1=new Double(1.0);,是從堆new一個(gè)對(duì)象妇多,d2同理伤哺。因此d1和d2存放的指針不同,指向的對(duì)象不同者祖,所以不相等立莉。
小結(jié):
1.以上提到的幾種基本類型包裝類均實(shí)現(xiàn)了常量池技術(shù),但他們維護(hù)的常量?jī)H僅是【-128至127】這個(gè)范圍內(nèi)的常量咸包,如果常量值超過(guò)這個(gè)范圍桃序,就會(huì)從堆中創(chuàng)建對(duì)象杖虾,不再?gòu)某A砍刂腥±锰薄1热纾焉线吚痈某蒊nteger i1 = 400; Integer i2 = 400;奇适,很明顯超過(guò)了127坟比,無(wú)法從常量池獲取常量,就要從堆中new新的Integer對(duì)象嚷往,這時(shí)i1和i2就不相等了葛账。
2.String類型也實(shí)現(xiàn)了常量池技術(shù),但是稍微有點(diǎn)不同皮仁。String型是先檢測(cè)常量池中有沒(méi)有對(duì)應(yīng)字符串籍琳,如果有菲宴,則取出來(lái);如果沒(méi)有趋急,則把當(dāng)前的添加進(jìn)去喝峦。
常量池
Interger中的128(-128~127)
a.當(dāng)數(shù)值范圍為-128~127時(shí):如果兩個(gè)new出來(lái)Integer對(duì)象,即使值相同呜达,通過(guò)“==”比較結(jié)果為false谣蠢,但兩個(gè)對(duì)象直接賦值,則通過(guò)“==”比較結(jié)果為“true查近,這一點(diǎn)與String非常相似眉踱。
b.當(dāng)數(shù)值不在-128~127時(shí),無(wú)論通過(guò)哪種方式霜威,即使兩個(gè)對(duì)象的值相等谈喳,通過(guò)“==”比較,其結(jié)果為false戈泼;
c.當(dāng)一個(gè)Integer對(duì)象直接與一個(gè)int基本數(shù)據(jù)類型通過(guò)“==”比較叁执,其結(jié)果與第一點(diǎn)相同;
d.Integer對(duì)象的hash值為數(shù)值本身矮冬;
為什么是-128-127?
????在Integer類中有一個(gè)靜態(tài)內(nèi)部類IntegerCache谈宛,在IntegerCache類中有一個(gè)Integer數(shù)組,用以緩存當(dāng)數(shù)值范圍為-128~127時(shí)的Integer對(duì)象胎署。