在看深刻理解java虛擬機中的自動裝箱的陷阱部分,記錄一下。java
public class Test { public static void main(String[] args) { try { 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); System.out.println(e==f); System.out.println(c==(a+b)); System.out.println(c.equals(a+b)); System.out.println(g==(a+b)); System.out.println(g.equals(a+b)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
運行結果以下:數組
true false true true true false
可能對運行結果比較疑惑,看一下編譯後真正的樣子。緩存
將編譯後的class文件反編譯後獲得的內容以下:code
public class Test { public static void main(String[] args) { try { Integer a = Integer.valueOf(1); Integer b = Integer.valueOf(2); Integer c = Integer.valueOf(3); Integer d = Integer.valueOf(3); Integer e = Integer.valueOf(321); Integer f = Integer.valueOf(321); Long g = Long.valueOf(3L); System.out.println(c == d); System.out.println(e == f); System.out.println(c.intValue() == a.intValue() + b.intValue()); System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue()))); System.out.println(g.longValue() == a.intValue() + b.intValue()); System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue()))); } catch (Exception e) { e.printStackTrace(); } } }
可是仍是有疑惑,c==d和e==f的結果爲何不一樣呢?對象
看一下valueOf的實現:虛擬機
public static Integer valueOf(int i) { assert Integer.IntegerCache.high >= 127; if (i >= Integer.IntegerCache.low && i <= Integer.IntegerCache.high) return Integer.IntegerCache.cache[i + (-Integer.IntegerCache.low)]; return new Integer(i); }
原來Integer有個內部類IntegerCache緩存了從-128至127的Integer對象數組,若是在這個範圍內就直接返回數組內的對象,不然就返回新對象。io
順便看一下equals(Object obj)方法的實現:編譯
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
先判斷是否類型相同,而後在比較基礎類型int值是否相等。class
因此,使用對象類型和基礎類型比較的時候須要謹慎一點。基礎