java中,每個基本數據類型都是與類(包裝類)相對應的:
int對應的類是Integer;char對應的類是Character;float對應的類是Float;long對應的類是Long
byte對應的類是Byte;short對應的類是Short;double對應的類是Double;boolean對應的類是Boolean
一、
1)int則是java的一種基本數據類型,其定義的是基本數據類型變量 ;Integer是int的包裝類,其定義的是引用類型變量
2)基本數據類類型存的是數值本身;引用類型變量在內存放的是數據的引用
3) 基本類型比較的是他們的值大小(通過==),而引用類型比較的是他們的引用地址
4) Integer變量必須實例化后才能使用,而int變量不需要
5)Integer實際是對象的引用,當new一個Integer時,實際上是生成一個指針指向此對象;而int則是直接存儲數據值
6)Integer的默認值是null,int的默認值是0
二、
Integer和int的比較
1)由於Integer變量實際上是對一個Integer對象的引用,所以兩個通過new生成的Integer變量永遠是不相等的(因為new生成的是兩個對象,其內存地址不同)。
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.print(i == j); //false
2)Integer變量和int變量比較時,只要兩個變量的值是向等的,則結果為true(因為包裝類Integer和基本數據類型int比較時,java會自動將Integer拆箱為int,然后進行比較,實際上就變為兩個int變量的比較)
Integer i = new Integer(1);
int j = 1;
System.out.print(i == j); //true
3)非new生成的Integer變量和new Integer()生成的變量比較時,結果為false。(因為非new生成的Integer變量指向的是java常量池中的對象,而new Integer()生成的變量指向堆中新建的對象,兩者在內存中的地址不同)
Integer i = new Integer(1);
Integer j = 1;
System.out.print(i == j); //false
4)對於兩個非new生成的Integer對象,進行比較時,如果兩個變量的值在區間-128到127之間,則比較結果為true,如果兩個變量的值不在此區間,則比較結果為false
Integer i = 110;
Integer j = 110;
System.out.print(i == j); //true(因為-128到127java已經進行了緩存,所以i和j指向的是同一塊內存,即同樣的引用地址)
Integer i = 128;
Integer j = 128;
System.out.print(i == j); //false
java在編譯Integer i = 110 時,會翻譯成為Integer i = Integer.valueOf(110);而java API中對Integer類型的valueOf的定義如下:
public static Integer valueOf(int i){
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high){
return IntegerCache.cache[i + (-IntegerCache.low)];
}
return new Integer(i);
}
java對於-128到127之間的數,會進行緩存,Integer i = 127時,會將127進行緩存,下次再寫Integer j = 127時,就會直接從緩存中取,就不會new了
三、
舉例:
注意:
①Integer與new Integer不會相等。不會經歷拆箱過程,
②兩個都是非new出來的Integer,如果數在-128到127之間則是true,否則為false ;java在編譯Integer i2 = 128的時候,
被翻譯成 Integer i2 = Integer.valueOf(128);而valueOf()函數會對-128到127之間的數進行緩存
③兩個都是new出來的,引用地址不同,false
④int和integer(無論new否)比,都為true,因為會把Integer自動拆箱為int再去比
解析:
A: Integer 與 int 比較的時候將Integer拆箱轉成int,然后再比較大小,true
B: Integer i01 = 59;默認處理Integer i01 =Integer.valueOf(59); i01與 i03數值在-128 - 127之間,所以在cache緩存中獲取Integer對象,他們引用地址是一樣的。true
C: i03獲取的是cache中緩存好的的Integer地址,而i04是重新在堆中創建一個地址,所以兩個地址是不一樣的 .false
D:同A
其實Integer與int類型的賦值與比較最關鍵的一點就是:這兩個變量的類型不同。Integer是引用類型,int是原生數據類型。
我們分四種情況來討論:
1) Integer與int類型的賦值
a.把Integer類型賦值給int類型。此時,int類型變量的值會自動裝箱成Integer類型,然后賦給Integer類型的引用,這里底層就是通過調用valueOf()這個方法來實現所謂的裝箱的。
b.把int類型賦值給Integer類型。此時,Integer類型變量的值會自動拆箱成int類型,然后賦給int類型的變量,這里底層則是通過調用intValue()方法來實現所謂的拆箱的。
2) Integer與int類型的比較
這里就無所謂是誰與誰比較了,Integer == int與int == Integer的效果是一樣的,都會把Integer類型變量拆箱成int類型,然后進行比較,相等則返回true,否則返回false。同樣,拆箱調用的還是intValue()方法。
3) Integer之間的比較
這個就相對簡單了,直接把兩個引用的值(即是存儲目標數據的那個地址)進行比較就行了,不用再拆箱、裝箱什么的。
4) int之間的比較
這個也一樣,直接把兩個變量的值進行比較。
值得注意的是:對Integer對象,JVM會自動緩存-128~127范圍內的值,所以所有在這個范圍內的值相等的Integer對象都會共用一塊內存,而不會開辟多個;超出這個范圍內的值對應的Integer對象有多少個就開辟多少個內存。
四、
堆和棧的區別是什么?
堆和棧是編譯器划分的內存空間。
棧上分配的內存,編譯器會自動收回;堆上分配的內存,要通過free來顯式地收回。
棧是系統自動分配,堆是需要程序員自己申請(new出來)
哪些變量會在棧中分配空間,哪些變量會在堆中分配空間?
函數局部變量、參數,一些臨時對象都在棧中分配空間。全局變量存儲在堆中分配空間。