Integer与int的比较与区别
如题:
Integer a = new Integer(3);
Integer b = 3;
int c = 3;
System.out.println(a == b);
System.out.println(a == c);
Integer f1 = 100, f2 = 100;
Integer f3 = 200;
Integer f4 = 200;
System.out.println(f1 == f2);
System.out.println(f3 == f4);
System.out.println(f3 == (f1 + f2));
结果:
a==b的答案是:false
无论如何,Integer与new Integer不会相等。不会经历拆箱过程,Integer的引用指向堆,而new Integer指向专门存放他的内存(常量池),他们的内存地址不一样,所以为false
原因很简点,因为对与对象来说 “==” 判断的依据是两个对象的地址是否相等,显然a是新建的对象和b自动包装出来的堆相指向的不是同一个地址,所以为false。
a==c的答案是:true
包装类Integer和基本类型的数据在比对时会自动拆箱(调用Integer的intValue()方法)进行比较。
int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比。
因为c是一个基本类型的数据,包装类Integer和基本类型的数据在比对时会自动拆箱(调用Integer的intValue()方法)进行比较,即使用a对象的数值和基本类型c进行数值大小的比较。
f1 == f2 的答案是:true
f3 == f4 的答案:false
两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false
java在编译Integer x = 1的时候,被翻译成-> Integer x = Integer.valueOf(1);
JDK源码的valueOf函数式这样的:public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; //判断是否在缓存数组里,如果在,直接返回 return new Integer(i);//不在缓存的数组里,直接new一个新的对象返回 }
看一下IntegerCache这个类:
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() {} }
这是一个内部静态类,该类只能在Integer这个类的内部访问,这个类在初始化的时候,会去加载JVM的配置,如果有值,就用配置的值初始化缓存数组,否则就缓存-128到127之间的值。
f3==(f1+f2)的答案:true
Integer对象之间在执行符号运算时,会自动拆箱,(调用Integer的intValue()方法)
因为Integer对象之间在执行符号运算时,会自动拆箱,(调用Integer的intValue()方法),所以f1+f2是其对象数值的相加,得到的结果是int类型的200,此时再次和f3进行比较,因为200是int类型的基本类型数据,所以f3也会进行自动拆箱,和之前运算得到的200进行比较,值相等,结果为true。
下面附上编译后的字节码文件(已经进行过反编译):
Integer a = new Integer(3);
Integer b = Integer.valueOf(3);
int c = 3;
System.out.println(a == b);
System.out.println(a.intValue() == c);
Integer f1 = Integer.valueOf(100);
Integer f2 = Integer.valueOf(100);
Integer f3 = Integer.valueOf(200);这个相当于new了两个对象,==比较的是引用变量的内存地址,所以为false
Integer f4 = Integer.valueOf(200);
System.out.println(f1 == f2);
System.out.println(f3 == f4);
System.out.println(f3.intValue() == f1.intValue() + f2.intValue());
两个Integer对象都是new出来的,都为false