關於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方法比較的是對象的值(前提是兩者屬於同一個對象類型),而對於基本數據類型,==符號比較的是值
那麼對於第一個輸出,可能就有點疑惑了,爲什麼明明是比較對象的地址,卻輸出了true,而不是false,這裏又有一點要補充啦!
因爲在jdk實現的時候,考慮到一些對象可能會經常使用,所以在內部創建了一個數組,將常用對象提前做好了創建(Integer是-127~128),要使用的時候,返回的其實是同一個對象,而對於超出範圍的值,就會創建一個新的對象啦!
再來看第五個輸出,返回了true,這裏其實是自動拆包,在包裝類的==符號遇到算術運算的時候,就會發生自動拆包,所以比較的是兩者的值
那麼下面來總結一下:
1.在==運算的時候,如果兩端中任何一端含有算術表達式,就會發生自動解包,這時比較的是值
2.在==運算時,兩端都沒有算術表達式,就不會解包,這時比較的是對象的地址(這樣使用很危險)
3.equals可以比較對象的值,比較推薦使用,但前提是要相同對象類型,比如在上面倒數第二個輸出中,雖然值相等,但是一個是Integer,一個是Long,就會返回false,但是如果是基本數據類型int 和 long ,他們其實是可以相等的