java面試題之int和Integer的區別


int和Integer的區別

1、Integer是int的包裝類,int則是java的一種基本數據類型 
2、Integer變量必須實例化后才能使用,而int變量不需要 
3、Integer實際是對象的引用,當new一個Integer時,實際上是生成一個指針指向此對象;而int則是直接存儲數據值 
4、Integer的默認值是null,int的默認值是0

延伸: 
關於Integer和int的比較 
1、由於Integer變量實際上是對一個Integer對象的引用,所以兩個通過new生成的Integer變量永遠是不相等的(因為new生成的是兩個對象,其內存地址不同)。

Integer i = new Integer(100);
Integer j = new Integer(100);
System.out.print(i == j); //false

2、Integer變量和int變量比較時,只要兩個變量的值是向等的,則結果為true(因為包裝類Integer和基本數據類型int比較時,java會自動拆包裝為int,然后進行比較,實際上就變為兩個int變量的比較)

Integer i = new Integer(100);
int j = 100;
System.out.print(i == j); //true

3、非new生成的Integer變量和new Integer()生成的變量比較時,結果為false。(因為非new生成的Integer變量指向的是java常量池中的對象,而new Integer()生成的變量指向堆中新建的對象,兩者在內存中的地址不同)

Integer i = new Integer(100);
Integer j = 100;
System.out.print(i == j); //false

4、對於兩個非new生成的Integer對象,進行比較時,如果兩個變量的值在區間-128到127之間,則比較結果為true,如果兩個變量的值不在此區間,則比較結果為false

Integer i = 100;
Integer j = 100;
System.out.print(i == j); //true
Integer i = 128;
Integer j = 128;
System.out.print(i == j); //false

對於第4條的原因: 
java在編譯Integer i = 100 ;時,會翻譯成為Integer i = Integer.valueOf(100);,而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了

 

簡述:int與Integer的區別:

對於它們,我們可能只是知道簡單的區別。Integer是int的一個封裝類,int的初始值為0,而Integer的初始值為null。但是他們之間真的僅僅只有這些區別嗎?我覺得答案是否定的,於是我決定深入到jdk源碼中一探究竟。看看Integer與int到底有什么區別。

 

執行代碼:

復制代碼
 1 public class IntegerTest {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         int intNum = 127;
 6         Integer integerNum = 127;
 7         Integer integerNewNum = new Integer(127);
 8         
 9         //比較兩個int變量
10         int intNum1 = 127;
11         System.out.print("int與int:");
12         System.out.println(intNum==intNum1);
13                 
14         
15         //比較int與Integer區別
16         System.out.print("int與Integer:");
17         System.out.println(intNum==integerNum);
18         
19         //比較int與Integer區別
20         System.out.print("int與NewInteger:");
21         System.out.println(intNum==integerNewNum);
22         
23         //比較Integer與NewInteger
24         System.out.print("Integer與NewInteger:");
25         System.out.println(integerNum==integerNewNum);
26                 
27         //比較兩個NewInteger
28         Integer integerNewNum1 = new Integer(127);
29         System.out.print("NewInteger與NewInteger:");
30         System.out.println(integerNewNum==integerNewNum1);
31                 
32         //比較兩個小於128的聲明變量
33         Integer integerNum1 = 127;
34         System.out.print("小於128的Integer與Integer:");
35         System.out.println(integerNum==integerNum1);
36         
37         //比較兩個大於等於128的聲明變量
38         Integer integerNum2 = 128;
39         Integer integerNum3 = 128;
40         System.out.print("大於等於128的Integer與Integer:");
41         System.out.println(integerNum2==integerNum3);
42         
43     }
44 
45 }
復制代碼

 

 

運行結果:

復制代碼
int與Integer:true
int與NewInteger:true
Integer與NewInteger:false
int與int:true
NewInteger與NewInteger:false
小於128的Integer與Integer:true
大於等於128的Integer與Integer:false
復制代碼

 

問題:

1.為什么當我們使用數值相等的integerNum、integerNewNum與intNum比較時結果為true?

2.為什么當我們使用數值相等的integerNum與integerNewNum進行比較時結果為false?

3.為什么integerNum與integerNum進行比較時會出現大於128和小於等於128不同結果的情況?

 

我的理解:

一下所有討論問題的前提是:兩個int型變量所賦值的數值相同時,比較結果為true,即12行的結果。

1.17行與21行所得到的結果為true,其實我們如果我們從源碼來理解就會知道其本質了。在此之前我們應該先補充一個感念,Integer integerNum =127在執行時會被翻譯成

Integer integerNum = Integer.valueOf(127)。源碼如下

 

復制代碼
1 public static Integer valueOf(String arg) throws NumberFormatException {
2         return valueOf(parseInt(arg, 10));
3     }
4 
5     public static Integer valueOf(int arg) {
6         return arg >= -128 && arg <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[arg + 128]
7                 : new Integer(arg);
8     }
復制代碼
復制代碼
 1 private static class IntegerCache {
 2         static final int low = -128;
 3         static final int high;
 4         static final Integer[] cache;
 5 
 6         static {
 7             int arg = 127;
 8             String arg0 = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
 9             int arg1;
10             if (arg0 != null) {
11                 try {
12                     arg1 = Integer.parseInt(arg0);
13                     arg1 = Math.max(arg1, 127);
14                     arg = Math.min(arg1, 2147483518);
15                 } catch (NumberFormatException arg3) {
16                     ;
17                 }
18             }
19 
20             high = arg;
21             cache = new Integer[high - -128 + 1];
22             arg1 = -128;
23 
24             for (int arg2 = 0; arg2 < cache.length; ++arg2) {
25                 cache[arg2] = new Integer(arg1++);
26             }
27 
28             assert high >= 127;
29 
30         }
31     }
復制代碼
復制代碼
1 private final int value;
2 public Integer(int arg0) {
3         this.value = arg0;
4     }
5 
6     public Integer(String arg0) throws NumberFormatException {
7         this.value = parseInt(arg0, 10);
8     }
復制代碼

 

以上jdk源碼可以得到,Integer 無論是聲明還是新建對象,最終所得的值都是int型,所以我們問題1就等到了答案。兩個int型比較所得結果必然是ture.

 

2.25行所得結果為false,為什么呢?不是都轉成int型嘛?結果不是應該為false嘛?額額額額。new了地址就不一樣了所以當我們使用"=="進行比較時盡管數值相同,但內存地址卻早已不相同。這就涉及到了下一篇博文中會講的"=="與".equals"的區別。

 

3.為什么會出現問題3這種情況,128會是一個零界點呢?其實答案在源碼中我們也可以找到

復制代碼
1 public static Integer valueOf(String arg) throws NumberFormatException {
2         return valueOf(parseInt(arg, 10));
3     }
4 
5     public static Integer valueOf(int arg) {
6         return arg >= -128 && arg <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[arg + 128]
7                 : new Integer(arg);
8     }
復制代碼

當arg大於等於-128且小於等於127時則直接從緩存中返回一個已經存在的對象。如果參數的值不在這個范圍內,則new一個Integer對象返回。

 

以上就是int與Integer的區別,我們再日常的項目或者練習中經常拿不准該使用int還是Integer,但看了這篇博文你應該已經有了自己的答案了吧!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM