java Integer 自動包裝與解包


關於java的自動包裝機制想必大家都用過吧,一般這些機制都用於在往容器中存儲基本類型數據的時候,因為容器中不允許存在基本數據類型,所以就會調用自動包裝機制,將基本數據類型轉換為對象,將基本數據保存在對象中,並且提供一些基本方法,但是自動包裝機制存在一些陷阱,使用不當就會出錯

先看看下面一個例子吧

 1 package test;
 2 
 3 public class AutoPack {
 4     public static void main(String[] args) {
 5         Integer a=1;
 6         Integer b=2;
 7         Integer c=3;
 8         Integer d = 3;
 9         Integer e=321;
10         Integer f=321;
11         Long g=3L;
12         System.out.println(c==d);//true
13         System.out.println(e==f);//false
14         System.out.println(c==(a+b));//true
15         System.out.println(c.equals(a+b));//true
16         System.out.println(g==(a+b));//true
17         System.out.println(g.equals(a+b));//false  //不是同一類型
18         System.out.println(g.equals((long)(a+b)));//true   首先比較是不是同一類型,再比較值
19     }
20 }

上面例子中的輸出你都做對了嗎?如果有疑惑,請看我下面的解答

首先我們得請出一個前提:對於對象類型,==符號表示比較對象的所在的物理地址,equals方法比較的是對象的值(前提是兩者屬於同一個對象類型),而對於基本數據類型,==符號比較的是值

然后我們再來看一看Integer的內部實現,Integer有三種創建方法,分別是

Integer a = new Integer(1);  //創建新的類

Integer b = Integer.valueOf(2);  

Integer c = 3;    //自動包裝,會調用valueOf方法

上面的三種方法中,第一種方法所創建的是一個全新的Integer對象,這樣的對象在用 == 比較時是肯定不相同的,只能通過 equals 方法進行比較

,第二種方法和第三種方法都顯式或者隱式的調用了ValueOf方法,所以下面我們來看一下ValueOf方法

   public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

valueOf方法首先判斷數字是否大於low(-128)並且小於數字(127),如果滿足條件,則直接從IntegerCache中返回這個數(IntegerCache用於存儲一些常用的數,防止重復創建),

所以只要是用 valueOf 或者Integer = num 這兩種方法創建的對象,其值小於127且大於-128的,無論對其進行 == 比較還是equals 比較,都是true

對於不滿足這個范圍的數,無論怎么創建,都是一個新的對象,是只能通過equals比較的,接下來我們再看看equals方法

 

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

equals很簡單,首先比較兩者的類型是否一致,如果類型不一致,直接返回false,否則,再比較兩者的值,相同則返回true

那么現在你再回過頭去看上面的輸出,是不是清晰明了呢

還有一點就是上面的第三個和第五個輸出了,因為等式兩邊都運用了算術運算符,所以會自動拆包,拆包后比較的就是兩者的value了

 

那么下面來總結一下:

1.在==運算的時候,如果兩端中任何一端含有算術表達式,就會發生自動解包,這時比較的是值

2.在==運算時,兩端都沒有算術表達式,就不會解包,這時比較的是對象的地址(這樣使用很危險)

3.equals可以比較對象的值,比較推薦使用,但前提是要相同對象類型,比如在上面倒數第二個輸出中,雖然值相等,但是一個是Integer,一個是Long,就會返回false,但是如果是基本數據類型int 和 long ,他們其實是可以相等的

4.Integer中有IntegerCache,會對-128到127的值進行緩存,所以在這個范圍內只要不用new 關鍵字創建Integer對象,那么這些對象都是同一個對象


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM