java基礎鞏固系列(二):Integer與int之間的區別
在JDK1.5之後引入了自動裝箱(autoboxing)與自動拆箱(unboxing),這讓很多對java的初學者感到很疑惑,我剛才也是其中一員。
首先,有一些基本的概念需要了解:
1、Ingeter是int的包裝類,int的初值為0,Ingeter的初值為null。
2、Integer是一個類,用Integer宣告一個變數是一個物件型別(或者說引用型別);int是基本型別,用int宣告的變數是非物件型別,即不能在其上呼叫方法。
3、“==”作用於物件上的時候,其比較的是物件的引用本身的值(或者說物件的地址更容易理解),而作用於基本型別的時候比較的就是基本型別的值。
然後,我們需要明白兩個基本概念:自動裝箱與自動拆箱
Integer a=1;//這就是一個自動裝箱,如果沒有自動裝箱的話,需要這樣Integer a=new Integer(1)
int b=a;//這就是一個自動拆箱,如果沒有自動拆箱的話,需要這樣:int b=a.intValue()
這樣就能看出自動裝箱和自動拆箱是簡化了基本資料型別和相對應物件的轉化步驟
接下來我們會用具體的程式碼敘述Integer與int之間的區別:
1.、Integer x = 10與Integer y = new Integer(10)不會相等。因為這兩者在比較的時候不會經歷拆箱過程,後者的引用指向堆,而前者指向專門存放他的記憶體(-128~127的常量池),他們的記憶體地址不一樣,所以為false、
public static void main(String[] args) {
Integer i = 10;
Integer j = new Integer(10);
System.out.println(i == j); //false
}
2、兩個都不是new出來的Integer,如果數在-128到127之間,則是true,否則為false
public static void main(String[] args) {
Integer i = 10;
Integer j = 10;
System.out.println(i == j); //true
}
很多人在這裡不懂為什麼,這裡就需要說下原因了:public static void main(String[] args) { Integer i = 128; Integer j = 128; System.out.println(i == j); //false }
java在編譯Integer i = 10的時候,被翻譯成Integer i = Integer.valueOf(10);
JDK原始碼的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);
}
對於-128到127之間的數,會進行快取,Integer i = 10時,會將10進行快取,下次再寫Integer j = 10時,就會直接從快取中取,就不會new了。
所以第一段程式碼的結果是true.
反之,對於-128到127之外的數,參照valueOf函式的最後一行,會返回一個new(新的) Integer物件。
當Integer i =128的時候產生了第一個Integer物件,當Integer j = 128的時候產生了第二個Integer物件,兩個物件的地址不同。
3、當兩者都是new Integer()出來的時候,兩者肯定不相同。
public static void main(String[] args) {
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println(i == j); //false
}
這裡有個比較,就是Integer i = 10;Integer j = 10是相同的,因為這時候i和j取得的都是快取中值為10的地址(參照2)
4、如果Integer型別與int型別比較,只要兩者的值相等,則Integer型別與int型別就相同。
public static void main(String[] args) {
Integer i = 128;
Integer j = new Integer(128);
int k =128;
System.out.println(i == j); //false
System.out.println(i == k); //true
System.out.println(j == k); //true
}
因為當Integer型別與int型別比較的時候,java是向下轉型的,所以Integer型別會自動拆箱變成int型別,所以,兩者在比較的時候會是比較數值。