簡單案例
首先我們要理解Integer是int基本數據類型的封裝類,也就是創建時應該是創建一個引用,并將引用指向這個對象。
當定義兩個個Integer對象為-128到127中時,其實是不會創建新的引用的的,但是當超過這個范圍后,就會創建一個新的引用,由于引用指向的地址都是不同的,所以兩個比較的地址不同,所以返回結果自然是false。
源碼如下:
private static classIntegerCache{static final int low = -128;static final int high;static final Integer cache[];static {
? ? // high value may be configured by property? ? int h = 127;
? ? String integerCacheHighPropValue =
? ? ? ? VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
? ? if (integerCacheHighPropValue != null) {
? ? ? ? try {
? ? ? ? ? ? int i = parseInt(integerCacheHighPropValue);
? ? ? ? ? ? i = Math.max(i, 127);
? ? ? ? ? ? // Maximum array size is Integer.MAX_VALUE? ? ? ? ? ? h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
? ? ? ? } catch( NumberFormatException nfe) {
? ? ? ? ? ? // If the property cannot be parsed into an int, ignore it.? ? ? ? }
? ? }
? ? high = h;
? ? cache = new Integer[(high - low) + 1];
? ? int j = low;
? ? for(int k = 0; k < cache.length; k++)
? ? ? ? cache[k] = new Integer(j++);
? ? // range [-128, 127] must be interned (JLS7 5.1.7)? ? assert IntegerCache.high >= 127;
}private IntegerCache() {}
}
分析:我們可以看到從-128~127的數全部被自動加入到了包裝類的對象池(也有稱常量池)里面,意味著這個段的數使用的常量值的地址都是一樣的。
原理如下:
1、== 這個運算在不出現算數運算符的情況下 不會自動拆箱,所以a1和 a2它們不是數值進行的比較,仍然是比較地址是否指向同一塊內存。
2、它們都在包裝類的對象池(也稱常量池)中存儲著。
3、編譯階段已經將代碼轉變成了調用valueOf方法,使用的是包裝類的對象池(也有稱常量池),如果超過了范圍則創建新的對象。
復雜實例[-128~127]
Integer i1 = 40;
? Integer i2 = 40;
? Integer i3 = 0;
? Integer i4 = new Integer(40);
? Integer i5 = new Integer(40);
? Integer i6 = new Integer(0);
? System.out.println("i1=i2? " + (i1 == i2));
? System.out.println("i1=i2+i3? " + (i1 == i2 + i3));
? System.out.println("i1=i4? " + (i1 == i4));
? System.out.println("i4=i5? " + (i4 == i5));
? System.out.println("i4=i5+i6? " + (i4 == i5 + i6));
? System.out.println("40=i5+i6? " + (40 == i5 + i6));----結果----(1)i1=i2? true
(2)i1=i2+i3? true
(3)i1=i4? false
(4)i4=i5? false
(5)i4=i5+i6? true
(6)40=i5+i6? true
注意點
1、當出現運算符的時候,Integer不可能直接用來運算,所以會進行一次拆箱成為基本數字進行比較
2、==這個符號,既可以比較普通基本類型,也可以比較內存地址看比較的是什么了
分析:
(1)號成立不用多說
(2)號成立是因為運算符自動拆箱
(3)(4)號是因為內存地址不同
(5)(6)號都是自動拆箱的結果
PS:equals方法比較的時候不會處理數據之間的轉型,比如Double類型和Integer類型。
超過范圍
假設一下,如果超出了這個范圍之后呢?正如前文所言,所有的都將成為新的對象
Integer i1 = 400;
? Integer i2 = 400;
? Integer i3 = 0;
? Integer i4 = new Integer(400);
? Integer i5 = new Integer(400);
? Integer i6 = new Integer(0);
? System.out.println("i1=i2? " + (i1 == i2));
? System.out.println("i1=i2+i3? " + (i1 == i2 + i3));
? System.out.println("i1=i4? " + (i1 == i4));
? System.out.println("i4=i5? " + (i4 == i5));
? System.out.println("i4=i5+i6? " + (i4 == i5 + i6));?
? System.out.println("400=i5+i6? " + (400 == i5 + i6));
----結果----i1=i2? false
i1=i2+i3? true
i1=i4? false
i4=i5? false
i4=i5+i6? true400=i5+i6? true