漫画:Integer 竟然有 6 种比较方式?












代码测试
以上代码的执行结果为:
true
false




首先,当我们将以上的测试代码编译为字节码(.class)之后,编码的代码如下:
可以看出在创建 Integer 时使用到了 valueOf
,它的实现源码如下:
从上述源码中可以看出这个方法中使用了 IntegerCache,IntegerCache 的源码如下:
从上述源码可以看出,在 Integer 的取值在 -128 到 127 之间时,它会复用已有的对象,因此在 i1(127)和 i2 使用 == 对比时值才会为 true,而当取值变为 128 时,则执行的结果为 false。
这一点其实在阿里巴巴的《Java开发手册》中也有相应的规定,规定的内容如下:
【强制】所有整型包装类对象之间值的比较,全部使用 equals 方法比较。
说明:对于 Integer var = ? 在 -128 至 127 之间的赋值,Integer 对象是在 IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用 == 进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。
注意事项
不仅如此,当我们使用 new Integer 时,无论值为多少都不能使用 == 比较,示例代码如下:
以上代码的执行结果为:
false
这是因为 new Integer 方法并没有使用到 IntegerCache,而是直接创建了新对象,因此就不能用 == 比较了。
小贴士:== 是用来直接比对两个对象的引用是否相同的,而 equals 则是用来对比两个对象的值是否相同的。


其他比较方式
compareTo
因为 Integer 类实现了 Comparable 接口,因此我们可以使用 compareTo 来对比两个值的大小,实现源码如下:
compareTo 的使用如下:
以上代码的执行结果为:
0
compareTo 的源码如下:
由此可以看出 compareTo 的返回值总共有三个:-1、0、1,其中 -1 表示前一值小于后一个值;0 表示两个值相等;1 表示前一个值大于后一个值,因此我们用它来比较两个 Integer 的值是否相等。
直接运算
compareTo 方法给我们了一个启发,我们可以直接将两个值进行相减,如果相减的值等于 0,则说明对比的两个值是相同的,示例代码如下:
以上代码的执行结果为:
true
intValue
我们可以使用 intValue 得到 Integer 的 int 值,然后再使用 == 进行比较,示例代码如下:
以上代码的执行结果为:
true
异或
异或是一个数学运算符,它应用于逻辑运算。在计算机中如果 a、b 两个值不相同,则异或结果为 1;如果 a、b 两个值相同,异或结果为 0。
比如:
1 异或 0=1
0 异或 0=0
1 异或 1=0
异或实现示例如下:
以上代码的执行结果为:
true
扩展知识:IntegerCache 值域修改
IntegerCache 默认的取值范围为 -128 到 127,但我们可以通过设置启动参数来调整 IntegerCache 的最大缓存值,比如我们可以配置虚拟机的启动参数 -XX:AutoBoxCacheMax=1000
,此配置表示将缓存的最大值设置为 1000,如果是 Idea 的配置如下:

此时我们编写一个测试代码:
以上代码的执行结果为:
true
从运行的结果可以看出 IntegerCache 的取值范围被成功的更改了。
总结
本文我们介绍了 Integer 的 6 种比较方式:==、equals、compareTo、直接运算,而 == 方式并不能用于 Integer 的比较,它只适用于非 new Integer 的一定范围内(-128~127),而后 5 种方式都可以正常用于 Integer 的比较,其中 equals 的比较方式是最为常用的。



互动话题
除了以上几种比较方式之外,你还知道其他的比较方式吗?欢迎评论区补充留言。
版权声明: 本文为 InfoQ 作者【王磊】的原创文章。
原文链接:【http://xie.infoq.cn/article/69c0adabd7d86964e94e3d96e】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论 (1 条评论)