Integer大小的比較

今天發現一個挺詭異的問題,先來看看下面這段代碼:

public class Test {  
    public static void main(String[] args) {  
        Integer a = 1000;  
        Integer b = 1000;  
        System.out.println("a==b : " + (a == b));  
        System.out.println("a.equals(b) : " + a.equals(b));  
    }  
}  

這段代碼的輸出結果是這樣的:

a==b : false  
a.equals(b) : true  


對於基本類型,以及基本類型的比較,我一直都是用“==”來進行比較的。一直沒注意這個問題,今天遇到了嚇一大跳。慶幸過去的程序中用“==”沒出現問題。把源碼拖出來看了一下,明白了,解釋如下:

平常我們使用Integer a = xxx;的時候,Integer類實際上是調用的是public static Integer valueOf(int i)方法。這個方法是這樣的。

   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);  
   }  

從上面代碼可以看出,當進行賦值操作時,Java將這個值分爲兩個區間來處理,即:

i 屬於[-128, 127]的時,返回IntegerCache.cache[i + offset];

i 屬於上面範圍以外時,返回new Integer(i)。

上面實例程序中,賦值超出[-128, 127]返回,所以返回爲new Integer(1000),而“==”比較是比較內存地址,那麼返回值肯定爲FALSE。

至此上面陳述的詭異問題就解開了。

但是Java爲什麼要這樣分區間處理呢,這不是使勁兒把我們往誤區裏勾引嗎?爲此我測試了這樣一個程序:賦值在[-128, 127]之間時。

public class Test {  
    public static void main(String[] args) {  
        Integer a = 10;  
        Integer b = 10;  
        System.out.println("a==b : " + (a == b));  
        System.out.println("a.equals(b) : " + a.equals(b));  
    }  
}  

 這段代碼的輸出結果是這樣的:

a==b : true  
a.equals(b) : true  

爲什麼出現這種現象呢?這就要問IntegerCache.cache[i + offset]了,跟蹤進去代碼如下:

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


static {  
    for(int i = 0; i < cache.length; i++)  
    cache[i] = new Integer(i - 128);  
}  

也就是說,當賦值在[-128, 127]區間時,Java是從同一個數據中取出同一個對象,即內存地址一樣,所以“==”操作返回TRUE;

那麼猜測Java這樣做的目的,可能[-128, 127]區間比較常用,這個區間內的Integer對象也作爲靜態變量初始化完成,這樣直接返回對象可以提高效率。

爲了防止不小心掉入這樣的陷阱,對於基本類型的比較,用“==”;而對於基本類型的封裝類型和其他對象,應該調用public boolean equals(Object obj)方法(複雜對象需要自己實現equals方法)。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章