首先弄清楚概念

int是一种基本数据类型,Integer是一个对象,需要实例化才能使用。它对int进行了包装,在Integer内部有一个对应的数值int变量

int和Integer的对比,经常被拿来作为面试题,下面就多种情况,通过源码分析其结果。我们将比较“==”和Equals两种结果。

第一种情况

java中两个integer数据比较大小 两个integer对象比较_赋值

结果:

java中两个integer数据比较大小 两个integer对象比较_赋值_02


这种情况是通过new关键字创建Integer对象,参数值一样。内部的int类型的value变量会保存参数值

java中两个integer数据比较大小 两个integer对象比较_缓存_03


既然Integer是对象,那么“”是要判断所引用的地址是否相等。两个不同的对象,地址必然不一样,所以“”结果为false。再看equals,Integer对equals进行了重写:

java中两个integer数据比较大小 两个integer对象比较_数组_04


我们从代码中发现,equals就是返回的Integer内部的value变量的值,也就是构造函数中传入的参数值。

java中两个integer数据比较大小 两个integer对象比较_赋值_05


所以equals就成了比较两个int类型数据的值,所以结果为true。

第二种情况

java中两个integer数据比较大小 两个integer对象比较_缓存_06


java中两个integer数据比较大小 两个integer对象比较_数组_07


这次Integer对象的创建,不是通过new直接构造了,那么直接赋值,Integer对象又是如何创建的呢。这种直接赋值的方式,会通过Integer的静态方法valueOf来负责执行。这里面就会涉及到IntegerCache.cache,一个Integer数组,值从-128~127,总共256个元素。凡是通过valueOf方法赋值的,如果值在-128~127,就会从缓存中获取,否则才会new一个新的对象。

Integer内部有一个类IntegerCache,它里面有一个cache数组,在初始化时就创建好了。
我们看到valueOf内部最终还是通过new来创建的Integer对象。当我们回头看输出结果时,就有点疑问了,“i1==i2 is true”?这不是比较的对象的地址吗,既然是两个对象,为什么结果是true呢?就是因为cache的存在,-128~127之间的数会从缓存中获取,而缓存中的对象是已经创建好的,如果值一样,那么获取到的缓存对象也是一个对象啊。所以结果就是同一个对象在比较。

第三种情况

既然有了第二种情况的这个认识,那么我们把数值改一下,如下:

java中两个integer数据比较大小 两个integer对象比较_赋值_08


java中两个integer数据比较大小 两个integer对象比较_缓存_09


这回应该好理解了吧,200已经超出了-128~127的范围,所以valueOf会执行new创建两个不同的对象。这就和第一种情况一样了。接下来我们看看int和Integer的比较。

第四种情况

java中两个integer数据比较大小 两个integer对象比较_缓存_10


java中两个integer数据比较大小 两个integer对象比较_数组_11


看到结果有没有点晕。“==”比较的不是地址吗,怎么两种不同类型结果是一样的呢?我们通过查看字节码就能发现其中的缘由。

java中两个integer数据比较大小 两个integer对象比较_赋值_12

看图中的红框,比较的时候Integer会通过intValue方法,读取内部的value变量和i1做比较,所以比较的是两个int类型数据,所以一样。也就是说,Integer和int比较时,会转换成两个int的值的比较。比较时,把i1和i2换一下位置,结果也是一样的。

第五种情况

java中两个integer数据比较大小 两个integer对象比较_缓存_13


java中两个integer数据比较大小 两个integer对象比较_缓存_14

上面呢用了两种数值,一个是缓存范围内,一个缓存范围内,结果都是一样的。i1创建一个对象,i2呢,要么从缓存中拿一个,要么new一个,反正和i1是两个对象,所以“==”结果是false,equals因为比较的是intValue的值,所以一样。

好了,int和Integer大致的表情况基本都涉及到了,即使再有其它形式,只要你明白其中的道理,怎么变都不怕。