Java 包裝類比較時帶來的問題

例1:緩存

Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e= 321;
        Integer f= 321;
        Long g = 3L;
        System.out.println(c == d); //1
        System.out.println(e == f); //2
        System.out.println(c == (a+b)); //3 
        System.out.println(c.equals(a+b));//4
        System.out.println(g == (a+b)); //5
        System.out.println(g.equals(a+b)); //6

輸出結果code

true
false
true
true
true
false

1.包裝類比較,不會自動拆包,可是Integer中會有一個cache 存儲-128到127的數,因此c與d的地址值相同。
2.地址值比較,沒用到cache
3.當 '=='時,右側發生自動拆包,因此實際上是int值在比較
4.a+b 時拆包成int,傳入Integer的equals方法進行自動裝包。equals方法內是值比較。
5.會拆包成基礎數據類型比較
6.包裝類的equals 會判斷類型,Long.equals(Object object)中判斷類型不符合,返回false。源碼

例2:基礎

Long a = 1L;
        Integer b = 1;
        System.out.println(a.equals(1)); //7
        System.out.println(a.equals(1L));
        System.out.println(a.equals(b));

輸出object

false
true
false

看包裝類源碼會發現比較時會先去判斷類型是否相同。
7.a.equals(1)時,int 1 裝包成Integer,天然和Long不一樣類型。數據類型

public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }

總結:
當使用自動拆包/裝包時,包裝類之間比較並不會自動拆包,是地址比較,其中還有緩存會影響結果。
用包裝類的equals方式比較時,因爲包裝類並不會自動去轉換類型,因此類型不一樣時,即便值相同,也會返回false。因此在用包裝類比較數值時,不要用'==',用equals方法時要注意類型相同,或者直接用基礎數據類型比較。方法

相關文章
相關標籤/搜索