目錄
突然發現自己對Integer i = 10;這種語法不太明白,於是乎有了這篇文章,那麼在講解 Integer 之前,我們先看下面這段代碼:
public static void main(String[] args) {
Integer i = 10;
Integer j = 10;
System.out.println(i == j);
Integer a = 128;
Integer b = 128;
System.out.println(a == b);
int k = 10;
System.out.println(k == i);
int kk = 128;
System.out.println(kk == a);
Integer m = new Integer(10);
Integer n = new Integer(10);
System.out.println(m == n);
}
大家可以先思考一下結果是什麼?
答案是:
至於爲什麼是這個結果,下面我們來一一介紹。
回到頂部
1、Integer 類簡介
首先我們大致看一下Integer是什麼,Integer 類在JDK1.0的時候就有了,它是一個類,是 int 基本數據類型的封裝類。
基本API如下:
圖片引用:http://blog.csdn.net/litong09282039/article/details/46309541
2、Integer 類和 int 的區別
①、Integer 是 int 包裝類,int 是八大基本數據類型之一(byte,char,short,int,long,float,double,boolean)
②、Integer 是類,默認值爲null,int是基本數據類型,默認值爲0;
③、Integer 表示的是對象,用一個引用指向這個對象,而int是基本數據類型,直接存儲數值。
4、回顧開頭的問題
public static void main(String[] args) {
Integer i = 10;
Integer j = 10;
System.out.println(i == j);
Integer a = 128;
Integer b = 128;
System.out.println(a == b);
int k = 10;
System.out.println(k == i);
int kk = 128;
System.out.println(kk == a);
Integer m = new Integer(10);
Integer n = new Integer(10);
System.out.println(m == n);
}
我們使用反編譯工具Jad,得到的代碼如下:
public static void main(String args[])
{
Integer i = Integer.valueOf(10);
Integer j = Integer.valueOf(10);
System.out.println(i == j);
Integer a = Integer.valueOf(128);
Integer b = Integer.valueOf(128);
System.out.println(a == b);
int k = 10;
System.out.println(k == i.intValue());
int kk = 128;
System.out.println(kk == a.intValue());
Integer m = new Integer(10);
Integer n = new Integer(10);
System.out.println(m == n);
}
打印結果爲:
首先,直接聲明Integer i = 10,會自動裝箱變爲Integer i = Integer.valueOf(10);Integer i 會自動拆箱爲 i.intValue()。
①、第一個打印結果爲 true
對於 i == j ,我們知道這是兩個Integer類,他們比較應該是用equals,這裏用==比較的是地址,那麼結果肯定爲false,但是實際上結果爲true,這是爲什麼?
我們進入到Integer 類的valueOf()方法:
分析源碼我們可以知道在 i >= -128 並且 i <= 127 的時候,第一次聲明會將 i 的值放入緩存中,第二次直接取緩存裏面的數據,而不是重新創建一個Ingeter 對象。那麼第一個打印結果因爲 i = 10 在緩存表示範圍內,所以爲 true。
②、第二個打印結果爲 false
從上面的分析我們知道,128是不在-128到127之間的,所以第一次創建對象的時候沒有緩存,第二次創建了一個新的Integer對象。故打印結果爲false
③、第三個打印結果爲 true
Integer 的自動拆箱功能,也就是比較兩個基本數據類型,結果當然爲true
④、第四個打印結果爲 true
解釋和第三個一樣。int和integer(無論new否)比,都爲true,因爲會把Integer自動拆箱爲int再去比較。
⑤、第五個打印結果爲 false
因爲這個雖然值爲10,但是我們都是通過 new 關鍵字來創建的兩個對象,是不存在緩存的概念的。兩個用new關鍵字創建的對象用 == 進行比較,結果當然爲 false。
5、測試
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println(c == d);
System.out.println(e == f);
System.out.println(c == (a + b));
System.out.println(c.equals((a+b)));
System.out.println(g == (a+b));
System.out.println(g.equals(a+b));
System.out.println(g.equals(a+h));
反編譯結果:
打印結果爲:
1 2 3 4 5 6 7 |
|
分析:第一個和第二個結果沒什麼疑問,Integer類在-128到127的緩存問題;
第三個由於 a+b包含了算術運算,因此會觸發自動拆箱過程(會調用intValue方法),==比較符又將左邊的自動拆箱,因此它們比較的是數值是否相等。
第四個對於c.equals(a+b)會先觸發自動拆箱過程,再觸發自動裝箱過程,也就是說a+b,會先各自調用intValue方法,得到了加法運算後的數值之後,便調用Integer.valueOf方法,再進行equals比較。
第五個對於 g == (a+b),首先計算 a+b,也是先調用各自的intValue方法,得到數值之後,由於前面的g是Long類型的,也會自動拆箱爲long,==運算符能將隱含的將小範圍的數據類型轉換爲大範圍的數據類型,也就是int會被轉換成long類型,兩個long類型的數值進行比較。
第六個對於 g.equals(a+b),同理a+b會先自動拆箱,然後將結果自動裝箱,需要說明的是 equals 運算符不會進行類型轉換。所以是Long.equals(Integer),結果當然是false
第七個對於g.equals(a+h),運算符+會進行類型轉換,a+h各自拆箱之後是int+long,結果是long,然後long進行自動裝箱爲Long,兩個Long進行equals判斷。
原文:https://blog.csdn.net/Teacher_Lee_ZZSXT/article/details/79230501