首先要明白 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