首先要明白 Integer 是包裝類型, int 是基礎類型。java
拿 Integer 來講其實就是在 int 外面又包裝了一下,繼承自 Number 接口數組
public final class Integer extends Number implements Comparable<Integer>
Integer a1 = 1; int a = a1;
上面第一行代碼會觸發裝箱的動做,jvm會轉換成
Integer a1 = Integer.valueOf(1);
第二行代碼會觸發拆箱的動做,jvm會轉換成
int a = a1.intValue();jvm
那麼看下面的例子code
Integer a1 = 1; int a = 1; Integer b = 1; Integer b1 = 4; Long a2 = 3l; System.out.println("b == a -> " + (b == a)); System.out.println("b.equals(a) -> " + (b.equals(a))); System.out.println("b1 == (a + a1) -> " + (b1 == (a + a1))); System.out.println("b1.equals(a + a1) -> " + (b1.equals(a + a1))); System.out.println("b1.equals(a + a2) -> " + (b1.equals(a + a2))); //輸出 b == a -> true b.equals(a) -> true b1 == (a + a1) -> true b1.equals(a + a1) -> true b1.equals(a + a2) -> false
上面的前面4個結果都返回 true, 也就是說 當一個基礎數據類型與封裝類進行==、+、-、*、/運算時,會將封裝類進行拆箱,對基礎數據類型進行運算。
最後一個返回 false,看下 equals 源代碼orm
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
經過源代碼能夠看到是類型不匹配,類型匹配的時候直接用的是 intValue 比較。對象
Integer d1 = 200; Integer d2 = 200; Integer d3 = 100; Integer d4 = 100; System.out.println("d1 == d2 -> " + (d1 == d2)); System.out.println("d1.equals(d2) ->" + (d1.equals(d2))); System.out.println("d3 == d4 -> " + (d3 == d4)); System.out.println("d3.equals(d4) -> " + (d3.equals(d4))); //輸出 d1 == d2 -> false d1.equals(d2) ->true d3 == d4 -> true d3.equals(d4) -> true
d1 == d2 返回false,這是由於包裝類常量池的存在繼承
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } // IntegerCache 爲 Integer 類中的靜態內部類 private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
當傳入的int值在 IntegerCache.low 和 IntegerCache.high 之間,就在 IntegerCache.cache 數據裏面取一個。在 IntegerCache 類中能夠看到 IntegerCache.low 的值爲 -128,IntegerCache.high 的值爲 127,IntegerCache.cache 就是預先初始化的一個數組,當傳入的值在 -128 到 127 之間的時候直接從數組取值,不然的話就要 new Integer()
因此,當 d3 == d4 的時候返回的都是同一個對象,結果相等, 當 d1 == d4 的時候,則是返回2個不一樣的對象(由於值大於128,建立了2個不一樣的對象),結果必然是不等的。接口
Double c1 = 100.0; Double c2 = 100.0; Double c3 = 200.0; Double c4 = 200.0; System.out.println("c1 == c2 -> " + (c1 == c2)); System.out.println("c1.equals(c2) ->" + (c1.equals(c2))); System.out.println("c3 == c4 -> " + (c3 == c4)); System.out.println("c3.equals(c4) -> " + (c3.equals(c4))); //輸出 c1 == c2 -> false c1.equals(c2) ->true c3 == c4 -> false c3.equals(c4) -> true
當類型是 Double 的時候就沒有這個常量池了,由於沒有一個肯定數量的值。get
Integer f = new Integer(100); Integer g = new Integer(100); System.out.println(f == g); //輸出 false
基本類型100經過包裝類Integer包裝後生產一個Integer對象的引用 f,而 == 使用來判斷兩個操做數是否有相等關係。若是是基本類型就直接判斷其值是否相等。如果對象就判斷是不是同一個對象的引用,顯然咱們new了兩個不一樣的對象。it