1. 程式人生 > >Integer值和int值的比較

Integer值和int值的比較

所謂裝箱,就是把基本型別用它們相對應的引用型別包起來,使它們可以具有物件的特質,如我們可以把int型包裝成Integer類的物件,或者把double包裝成Double,等等。 
所謂拆箱,就是跟裝箱的方向相反,將
IntegerDouble這樣的引用型別的物件重新簡化為值型別的資料 

javaSE5.0後提供了自動裝箱與拆箱的功能,此功能事實上是編譯器來幫您的忙,編譯器在編譯時期依您所編寫的方法,決定是否進行裝箱或拆箱動作。 
自動裝箱的過程:每當需要一種型別的物件時,這種基本型別就自動地封裝到與它相同型別的包裝中。 

自動拆箱的過程:每當需要一個值時,被裝箱物件中的值就被自動地提取出來,沒必要再去呼叫

intValue()doubleValue()方法。 
自動裝箱,只需將該值賦給一個型別包裝器引用,
java會自動建立一個物件。例如:Integer i=100;//沒有通過使用new來顯示建立,java自動完成。 

自動拆箱,只需將該物件值賦給一個基本型別即可,例如

· int i = 11;  

· Integer j = i; //自動裝箱  

· int k = j //自動拆箱 

然而在Integer的自動裝拆箱會有些細節值得注意:

public static void main(String[] args) {  

    Integer a=100;  

    Integer b=100;   

    Integer c=200;  

    Integer d=200;   

   System.out.println(a==b);   //1  

   System.out.println(a==100); //2     

  System.out.println(c==d);   //3  

  System.out.println(c==200); //4  

   }  
java種,"=="是比較objectreference而不是value,自動裝箱後,abcd都是Integer這個Oject,因此“==”比較的是其引用。按照常規思維,13都應該輸出false。但結果是: 
true 
true 
false 
true
結果

24,是因為ac進行了自動拆箱,因此其比較是基本資料型別的比較,就跟int比較時一樣的,“==”在這裡比較的是它們的值,而不是引用。 
對於結果
1,雖然比較的時候,還是比較物件的reference,但是自動裝箱時,java在編譯的時候 Integer a = 100; 被翻譯成-> Integer a = Integer.valueOf(100); 
關鍵就在於這個
valueOf()的方法。 

public static Integer valueOf(int i) {     

final int offset = 128;     

if (i >= -128 && i <= 127) { // must cache     

return IntegerCache.cache[i + offset];     

}     

return new Integer(i);     

}     

private static class IntegerCache {     

private IntegerCache(){}     

static final Integer cache[] = new Integer[-(-128) + 127 + 1];     

static {     

for(int i = 0; i < cache.length; i++)     

cache = new Integer(i - 128);     

}     

}   
根據上面的
jdk原始碼,java為了提高效率,IntegerCache類中有一個數組快取 了值從-128127Integer物件。當我們呼叫Integer.valueOfint i)的時候,如果i的值是>=-128<=127時,會直接從這個快取中返回一個物件,否則就new一個Integer物件。
具體如下: 

static final Integer cache[] = new Integer[-(-128) + 127 + 1]; //cache[]變成靜態  

static {  

        for(int i = 0; i < cache.length; i++)  

        cache[i] = new Integer(i - 128); //初始化cache[i]  

}  
這是用一個
for迴圈對陣列cache賦值,cache[255] = new Integer(255-128),也就是newl一個Integer(127) ,並把引用賦值給cache[255],好了,然後是Integer b= 127,流程基本一樣,最後又到了cache[255] = new Integer(255-128),這一句,那我們迷糊了,這不是又new了一個物件127嗎,然後把引用賦值給cache[255],我們比較這兩個引 用(前面宣告a的時候也有一個),由於是不同的地址,所以肯定不會相等,應該返回false啊!呵呵,這麼想你就錯了,請注意看for語句給 cache[i]初始化的時候外面還一個{}呢,{}前面一個大大的static關鍵字,是靜態的,那麼我們就可以回想下static有什麼特性了,只能 初始化一次,在物件間共享,也就是不同的物件共享同一個static資料

。那麼當我們Integer b = 127的時候,並沒有new出一個新物件來,而是共享了a這個物件的引用,記住,他們共享了同一個引用!!!,那麼我們進行比較a==b時,由於是同一個物件的引用(她們在堆中的地址相同),那當然返回true了!!!