为什么Java中“1000==1000”为false,而”100==100“为true?
在日常編程中,我們經常遇到一些看似簡單卻隱藏著復雜邏輯的問題。
比如,你是否想過為什么在 Java 中表達式1000==1000會返回 false,而 100==100 卻返回 true 呢?
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // 輸出:true
Integer c = 1000;
Integer d = 1000;
System.out.println(c == d); // 輸出:false
1、源碼追溯
解決問題,一定要深入本質,而解決編程問題,深入本質的方法就是對源碼一探究竟。
可能大家不知道 Integer a = 100 這種代碼是看哪個源碼,不要緊,我們可以看下其編譯后的 class 文件。
很明顯,我們得看 Integer 類的 valueOf 方法:
繼續看 IntegerCache :
為了防止大家不好理解,我這里為這個方法添加了詳細注釋:
private static class IntegerCache {
// 緩存的下界值,固定為-128
static final int low = -128;
// 緩存的上界值,可以通過系統屬性進行配置
static final int high;
// 緩存數組,用于存儲從low到high范圍內的Integer對象
static final Integer cache[];
static {
// 默認情況下,緩存的上界是127
int h = 127;
// 嘗試從系統屬性java.lang.Integer.IntegerCache.high中獲取自定義的上界值
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
// 將字符串轉換為整數
int i = parseInt(integerCacheHighPropValue);
// 確保自定義的上界至少為127,以包含Java規范要求的緩存范圍
i = Math.max(i, 127);
// 確保上界不超過Integer.MAX_VALUE - (-low) - 1,以防止數組大小超出Integer的最大值
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// 如果字符串無法解析為整數,忽略該屬性并保持默認的上界值
}
}
// 設置高界值
high = h;
// 初始化緩存數組,數組大小根據low和high計算得出
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++) {
// 創建Integer對象并填充數組
cache[k] = new Integer(j++);
}
// 斷言確保緩存的上界至少為127,符合Java語言規范
assert IntegerCache.high >= 127;
}
// 私有構造器,防止外部實例化這個內部類
private IntegerCache() {}
}
2、源碼解讀
其實這部分源碼不難理解,首先對于 valueOf 方法,當傳入的整型值在 -128-127 之間時,返回的是 IntegerCache 里面的值。
這個 IntegerCache 是在 Java 的 Integer 類中的一個內部靜態類 ,它緩存了 -128 到 127 之間的整數。
當我們聲明一個 Integer 對象并賦予一個在這個范圍內的值時,Java 實際上會返回一個預先創建好的對象引用。
這種機制可以有效減少內存的使用,并提高性能。
3、解答問題
看懂了源碼,在回到上面的問題,為什么表達式1000==1000會返回 false,而 100==100 卻返回 true 呢?
當我們使用 Integer 對象比較兩個數時,實際上是在比較對象的內存地址。由于“100”在緩存范圍內,兩個“100”實際上引用的是同一個對象,所以返回 true。
相反,“1000”不在緩存范圍內,即使數值相同,兩個“1000”也是不同的對象,因此內存地址不同,返回 false。
4、正確比較
其實對于 Integer 這種包裝類比較大小,我們應該使用 equals() 方法來比較兩個 Integer 對象的數值,而不是直接使用 == 操作符,除非我們確實想比較對象的引用。
Integer a = 100;
Integer b = 100;
System.out.println(a.equals(b)); // 輸出:true
Integer c = 1000;
Integer d = 1000;
System.out.println(c.equals(d)); // 輸出:true
這點在阿里開發手冊中也有詳細說明:
如果你是一名Java開發人員,我還是比較推薦你去閱讀這個手冊,對我們日常編碼規范還是挺有幫助的。
下載鏈接:https://pan.quark.cn/s/30d2c2c4239a
總結
以上是生活随笔為你收集整理的为什么Java中“1000==1000”为false,而”100==100“为true?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 布隆过滤器及其应用
- 下一篇: Java 8升级Java 11,升级必知