Integer值和int值的比較
所謂裝箱,就是把基本型別用它們相對應的引用型別包起來,使它們可以具有物件的特質,如我們可以把int型包裝成Integer類的物件,或者把double包裝成Double,等等。
所謂拆箱,就是跟裝箱的方向相反,將Integer及Double這樣的引用型別的物件重新簡化為值型別的資料
javaSE5.0後提供了自動裝箱與拆箱的功能,此功能事實上是編譯器來幫您的忙,編譯器在編譯時期依您所編寫的方法,決定是否進行裝箱或拆箱動作。
自動裝箱的過程:每當需要一種型別的物件時,這種基本型別就自動地封裝到與它相同型別的包裝中。
自動拆箱的過程:每當需要一個值時,被裝箱物件中的值就被自動地提取出來,沒必要再去呼叫
自動裝箱,只需將該值賦給一個型別包裝器引用,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種,"=="是比較object的reference而不是value,自動裝箱後,abcd都是Integer這個Oject,因此“==”比較的是其引用。按照常規思維,1和3都應該輸出false。但結果是:
true
true
false
true
結果
對於結果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類中有一個數組快取 了值從-128到127的Integer物件。當我們呼叫Integer.valueOf(int 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資料