App下載

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

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

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

下載 (1)

在Java中,對(duì)于整數(shù)類型的封裝類Integer,我們經(jīng)常會(huì)遇到一個(gè)有趣的現(xiàn)象:當(dāng)比較兩個(gè)小整數(shù)相等性時(shí),例如100和100,結(jié)果為?true?;但當(dāng)比較兩個(gè)大整數(shù)相等性時(shí),例如1000和1000,結(jié)果卻為?false?。這種現(xiàn)象背后隱藏著Java中整數(shù)對(duì)象緩存和對(duì)象引用的一些細(xì)微差別。

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);
    }
}
/**
 * 運(yùn)行結(jié)果
 * false
 * true
 */

為了提高性能和節(jié)省內(nèi)存,Java在內(nèi)部維護(hù)了一個(gè)整數(shù)緩存池,范圍是-128到127。當(dāng)我們創(chuàng)建一個(gè)Integer對(duì)象時(shí),如果數(shù)值在這個(gè)范圍內(nèi),Java會(huì)嘗試從緩存池中獲取已經(jīng)存在的Integer對(duì)象。這樣,當(dāng)我們使用相同數(shù)值的兩個(gè)Integer對(duì)象進(jìn)行比較時(shí),它們實(shí)際上是同一個(gè)對(duì)象的引用,因此比較結(jié)果為?true?。這種情況下,我們可以說它們是相等的。

然而,當(dāng)整數(shù)超出了緩存池的范圍,例如1000,Java會(huì)在堆中創(chuàng)建新的Integer對(duì)象,而不是從緩存池中獲取。盡管它們的數(shù)值相同,但它們?cè)趦?nèi)存中是不同的對(duì)象,具有不同的引用。因此,當(dāng)我們比較兩個(gè)大整數(shù)的相等性時(shí),由于比較的是對(duì)象的引用而不是數(shù)值本身,結(jié)果為?false?。

Snipaste_2024-02-02_09-45-17

這種行為可以通過Java的自動(dòng)裝箱(Autoboxing)和拆箱(Unboxing)機(jī)制來解釋。當(dāng)我們使用?==?運(yùn)算符比較兩個(gè)Integer對(duì)象時(shí),實(shí)際上是在比較它們的引用,而不是數(shù)值。如果我們想要比較它們的數(shù)值是否相等,應(yīng)該使用?equals()?方法,因?yàn)樵贗nteger類中,?equals()?方法被重寫以進(jìn)行數(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);
    }
}
/**
 * 運(yùn)行結(jié)果
 * true
 * true
 */

需要注意的是,這種整數(shù)緩存的行為只適用于整數(shù)類型的封裝類Integer,而不適用于其他封裝類如Long、Double等。

為了避免這種混淆和潛在的錯(cuò)誤,我們應(yīng)該始終使用?equals()?方法來比較兩個(gè)封裝類的相等性,尤其是在使用自動(dòng)裝箱和拆箱的情況下。此外,如果我們需要比較大整數(shù)的相等性,建議使用?equals()?方法或?qū)⒄麛?shù)轉(zhuǎn)換為基本數(shù)據(jù)類型進(jìn)行比較。

總結(jié)

Java中的整數(shù)封裝類Integer存在一個(gè)緩存池,對(duì)于-128到127之間的整數(shù),它們是同一個(gè)對(duì)象的引用,因此比較結(jié)果為true;對(duì)于超出該范圍的整數(shù),它們是不同的對(duì)象,比較結(jié)果為false。這是由于自動(dòng)裝箱和對(duì)象引用的特性所導(dǎo)致的,我們應(yīng)該謹(jǐn)慎使用==運(yùn)算符來比較封裝類的相等性,而是使用equals()方法來進(jìn)行數(shù)值的比較。


0 人點(diǎn)贊