1. 程式人生 > >Integer與int的區別

Integer與int的區別

徹底讓你明白 Integer 類和 int 基本資料型別的區別 2018年02月01日 16:46:33 鄭州尚學堂李老師 閱讀數:1866 標籤: Integer 類 int 基本資料型別  淺談 Integer 類 目錄

1、Integer 類簡介 2、Integer 類和 int 的區別 3、Integer 的自動拆箱和裝箱   ①、自動裝箱   ②、自動拆箱 4、回顧開頭的問題 5、測試

突然發現自己對Integer i = 10;這種語法不太明白,於是乎有了這篇文章,那麼在講解 Integer 之前,我們先看下面這段程式碼:

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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如下:

回到頂部 2、Integer 類和 int 的區別   ①、Integer 是 int 包裝類,int 是八大基本資料型別之一(byte,char,short,int,long,float,double,boolean)

②、Integer 是類,預設值為null,int是基本資料型別,預設值為0;

③、Integer 表示的是物件,用一個引用指向這個物件,而int是基本資料型別,直接儲存數值。

回到頂部 3、Integer 的自動拆箱和裝箱   自動拆箱和自動裝箱是 JDK1.5 以後才有的功能,也就是java當中眾多的語法糖之一,它的執行是在編譯期,會根據程式碼的語法,在生成class檔案的時候,決定是否進行拆箱和裝箱動作。

①、自動裝箱   一般我們建立一個類的時候是通過new關鍵字,比如:

? 1 Object obj = new Object();   但是對於 Integer 類,我們卻可以這樣:

? 1 Integer a = 128;   為什麼可以這樣,通過反編譯工具,我們可以看到,生成的class檔案是:

? 1 Integer a = Integer.valueOf(128);   這就是基本資料型別的自動裝箱,128是基本資料型別,然後被解析成Integer類。

②、自動拆箱   我們將 Integer 類表示的資料賦值給基本資料型別int,就執行了自動拆箱。

? 1 2 Integer a = new Integer(128); int m = a;   反編譯生成的class檔案:

? 1 2 Integer a = new Integer(128); int m = a.intValue();   簡單來講:自動裝箱就是Integer.valueOf(int i);自動拆箱就是 i.intValue();

回到頂部 4、回顧開頭的問題 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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,得到的程式碼如下:

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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、測試 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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));   反編譯結果:

列印結果為:

  • View Code? 1 2 3 4 5 6 7 true false true true true false true   分析:第一個和第二個結果沒什麼疑問,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判斷。