App下載

Java中Integer封裝:100和1000的相等性之謎

一語呢喃醉 2024-02-02 09:57:43 瀏覽數(shù) (2561)
反饋

在Java中,Integer封裝類的相等性比較常常讓人感到困惑。為什么當我們比較100和100時,結果為true,但比較1000和1000時,結果卻為false?這個現(xiàn)象涉及到Java的整數(shù)緩存和對象引用的差異。在本文中,我們將揭示這個有趣的現(xiàn)象的原因,并解釋如何正確比較整數(shù)封裝類的相等性。

下載 (1)

在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?。

Snipaste_2024-02-02_09-45-17

這種行為可以通過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ù)值的比較。


0 人點贊