我们大多数对于两者的认识停在:
Integer 是 int 的包装类,在初始化的时候,int 初始值为 0,而 Integer 的初始为 null 。
那么两者谁更占内存呢?
答案是 Integer 更占用内存,因为 int 是基础数据类型,占用的空间相对较小,而 Integer 是一个对象,需要存储对象的元数据,所以更占用内存。
在看问题之前,我们需要明确 == 是比较的什么?
对于引用数据类型的变量,== 比较的是两个引用指向的是否是同一个对象;
而对于基本数据类型的数据,== 比较的是两个变量的值是否相等 。
接下来我们通过几个例子,分析一下两者的区别
1、int 与非 new 出来的 Integer 比较
int i1 = 129;
Integer i2 = 129;
System.out.println(i1 == i2);
结果输出为 true
包装类 Integer 在与 基本数据类型 int 进行比较的时候,Integer 会自动拆箱成 int ,然后两者进行比较,其实就相当于两个基本数据类型在进行比较,只要值相同,则结果相同。
2、int 与 new 出来的 Integer 比较
int i3 = 130;
Integer i4 = new Integer(130);
System.out.println(i3 == i4);
结果输出为 true
原因和第一条是一致的,不管 Integer 是否为 new 出来的,与 int 比较时,都会自动拆箱为 int 类型,然后只需要比较两个值是否相等即可。
3、两个 new 出来的 Integer 比较
Integer i5=new Integer(190);
Integer i6=new Integer(190);
System.out.println(i5 == i6);
结果输出为 false
Integer 变量实际上是对一个 Integer 对象的引用,当 new 一个 Integer 的时候,会产生一个指针指向这个对象,new 了两个 Integer ,则会产生两个对象,两者内存地址不同,则会输出 false 结果。
4、一个 new 出来的 Integer 和一个非 new 出来的 Integer 比较
Integer i7 = new Integer(200);
Integer i8 = 200;
System.out.println(i7 == i8);
结果输出为 false
非 new 出来的 Integer 指向的是常量池中的对象,而 new 出来的对象则指向堆中新建的对象,两者的内存地址不同,所以输出结果 false 。
5、两个非 new 出来的 Integer 比较
Integer i9 = 127;
Integer i10 = 127;
System.out.println(i9 == i10);
Integer i11 = 129;
Integer i12 = 129;
System.out.println(i11 == i12);
第一个输出为 true ,第二个输出为 false
两个都是非 new 出来的 Integer 对象,为什么输出结果会不一样呢?
那是因为在编译 Integer i9 = 129 时,会翻译成 Integer i9 = Integer.valueOf(129); 查看源码
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
其中 IntegerCache.low = -128 ;
IntegerCache.high = 127 ;
可以看出,当数字介于 [-128,127] 之间时,java 会将其缓存,如上例 i9 = 127 ,会将其缓存,当 i10 = 127 时,则直接从缓存中取值,不会新建,所以 i9 和 i10 比较结果为 true 。
而 129 不在这个范围内,所以每次都会新建,所以 i11 和 i12 比较结果为 false 。