在Java中,Integer封裝類的相等性比較常常讓人感到困惑。為什么當我們比較100和100時,結果為true,但比較1000和1000時,結果卻為false?這個現(xiàn)象涉及到Java的整數(shù)緩存和對象引用的差異。在本文中,我們將揭示這個有趣的現(xiàn)象的原因,并解釋如何正確比較整數(shù)封裝類的相等性。
在Java中,對于整數(shù)類型的封裝類Integer,我們經常會遇到一個有趣的現(xiàn)象:當比較兩個小整數(shù)相等性時,例如100和100,結果為?true
?;但當比較兩個大整數(shù)相等性時,例如1000和1000,結果卻為?false
?。這種現(xiàn)象背后隱藏著Java中整數(shù)對象緩存和對象引用的一些細微差別。
public class Main {
public static void main(String[] args) {
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b);
Integer c = 100;
Integer d = 100;
System.out.println(c == d);
}
}
/**
* 運行結果
* false
* true
*/
為了提高性能和節(jié)省內存,Java在內部維護了一個整數(shù)緩存池,范圍是-128到127。當我們創(chuàng)建一個Integer對象時,如果數(shù)值在這個范圍內,Java會嘗試從緩存池中獲取已經存在的Integer對象。這樣,當我們使用相同數(shù)值的兩個Integer對象進行比較時,它們實際上是同一個對象的引用,因此比較結果為?true
?。這種情況下,我們可以說它們是相等的。
然而,當整數(shù)超出了緩存池的范圍,例如1000,Java會在堆中創(chuàng)建新的Integer對象,而不是從緩存池中獲取。盡管它們的數(shù)值相同,但它們在內存中是不同的對象,具有不同的引用。因此,當我們比較兩個大整數(shù)的相等性時,由于比較的是對象的引用而不是數(shù)值本身,結果為?false
?。
這種行為可以通過Java的自動裝箱(Autoboxing)和拆箱(Unboxing)機制來解釋。當我們使用?==
?運算符比較兩個Integer對象時,實際上是在比較它們的引用,而不是數(shù)值。如果我們想要比較它們的數(shù)值是否相等,應該使用?equals()
?方法,因為在Integer類中,?equals()
?方法被重寫以進行數(shù)值的比較。
public class Main {
public static void main(String[] args) {
Integer a = 1000;
Integer b = 1000;
System.out.println(a.equals(b));
Integer c = 100;
Integer d = 100;
System.out.println(c == d);
}
}
/**
* 運行結果
* true
* true
*/
需要注意的是,這種整數(shù)緩存的行為只適用于整數(shù)類型的封裝類Integer,而不適用于其他封裝類如Long、Double等。
為了避免這種混淆和潛在的錯誤,我們應該始終使用?equals()
?方法來比較兩個封裝類的相等性,尤其是在使用自動裝箱和拆箱的情況下。此外,如果我們需要比較大整數(shù)的相等性,建議使用?equals()
?方法或將整數(shù)轉換為基本數(shù)據類型進行比較。
總結
Java中的整數(shù)封裝類Integer存在一個緩存池,對于-128到127之間的整數(shù),它們是同一個對象的引用,因此比較結果為true;對于超出該范圍的整數(shù),它們是不同的對象,比較結果為false。這是由于自動裝箱和對象引用的特性所導致的,我們應該謹慎使用==運算符來比較封裝類的相等性,而是使用equals()方法來進行數(shù)值的比較。