#底層原理&經典面試題--Integer型別的大小比較
(1)
Integer i = 156;
Integer j =156;
if(i == j)
System.out.println(true);
System.out.println(true);
(2)
Integer i1 = 126;
Integer j1 = 126;
if(i1 == j1)
System.out.println(true);
System.out.println(true);
上面將各輸出什麼結果?
(1)true
(2)true true
我們來分析一下原理:
對Integer物件,JVM會自動快取-128~127範圍內的值,所以所有在這個範圍內的值相等的Integer物件都會共用一塊記憶體,而不會開闢多個;超出這個範圍內的值對應的Integer物件有多少個就開闢多少個記憶體。底層程式碼如下:
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);
}
因此,當使用Integer x = y進行宣告時,當y的值在-128127範圍內時,實際上獲取的是常量快取區的值,這時相等的Integer物件都會共用一塊記憶體地址,而不會開闢多個記憶體地址;當y的值在-128
案例:
package com.yzh.maven.main;
public class Test {
public static void main(String[] args) {
Integer i = 156;
Integer j =156;
if(i == j)
System.out.println(true);
System.out.println(true);
Integer i1 = 126; Integer j1 = 126; if(i1 == j1) System.out.println(true); System.out.println(true); Integer i2 = 102; int i3 = 102; System.out.println(i2 == i3); Integer i4 = 172; int i5 = 172; System.out.println(i4 == i5); Integer i6 = 172; Integer i7 = 172; System.out.println(i6 == i7);//false Integer i8 = new Integer(100); Integer i9 = new Integer(100); System.out.println(i8 == i9);//false Integer i10 = new Integer(190); Integer i11 = new Integer(190); System.out.println(i10 == i11);//false System.out.println(i8.hashCode() == i9.hashCode());//true,hashcode相同,物件不一定相同 /** * public int hashCode() { * return value; * } * private final int value; * public Integer(int value) { this.value = value; } */ }
}
其實Integer與int型別的賦值與比較最關鍵的一點就是:這兩個變數的型別不同。Integer是引用型別,int是原生資料型別。
我們分四種情況來討論:
1) Integer與int型別的賦值
a. 把int型別賦值給Integer型別。此時,int型別變數的值會自動裝箱成Integer型別,然後賦給Integer型別的引用,這裡底層就是通過呼叫valueOf()這個方法來實現所謂的裝箱的。
b. 把Integer型別賦值給int型別。此時,Integer型別變數的值會自動拆箱成int型別,然後賦給int型別的變數,這裡底層則是通過呼叫intValue()方法來實現所謂的拆箱的。
2) Integer與int型別的比較
在這種方式中,Integer == int與int == Integer的效果是一樣的,都會把Integer型別變數拆箱成int型別,然後進行比較,相等則返回true,否則返回false。同樣,拆箱呼叫的還是intValue()方法。
3) Integer之間的比較
這個種方式是直接把兩個引用的值(即是儲存目標資料的那個地址)進行比較,無需再拆箱、裝箱的過程。
例
Integer a1 = 160;
int a3 = 160;
System.out.println(a1++ == a3++);//true,會拆箱成int型別進行比較
Integer b1 = 150;
Integer b2 = 150;
Integer b3 = b1 + 1;
Integer b4 = b2 + 1;//還是Integer型別
System.out.println(b3 == b4);//flase