记录Java关于Integer的一个坑

在Java中,我们都知道对象判断使用==来进行地址判断,使用String的equals方法或者其它判断方法来进行内容的判断。虽然网络上关于这个坑的文章已经有很多了,但还是忍不住想在知乎上面分享一下,那么今天就来揭露以下Java中的int装箱类型Integer的一个坑人之处。

首先我们做个简单的测试,如下图,各位猜一下输出结果是什么样的。
在这里插入图片描述
结果如下图:
在这里插入图片描述
后面三个为true看起来都很正常,但为什么前两个Integer对象比对就是false呢,是不是两者的对象地址不同了?这里需要我们深一步探究这个问题。

首先我们知道,Integer在字面量进行赋值的时候使用到了这个类里的一个valueOf方法(具体原因使用Java反编译可得知),而这个方法上面有一段文档注释,这里我们翻译一下得到如下内容:

返回表示指定int值的整数实例。如果不需要新的整数实例,通常应优先使用该方法而不是构造函数整数(int),因为通过缓存频繁请求的值,该方法可能会产生显著更好的空间和时间性能。此方法将始终缓存-128到127(含)范围内的值,并且可能缓存此范围之外的其他值。

这个翻译内容里面提到了缓存,那么这个缓存是何方神圣呢,这里我们再往底层代码看一下。
在这里插入图片描述
看到上图红圈的代码得知,我们定义的数值如果在一个范围内的话,那么我们得到的Integer对象来源不一样了就。而这个IntegerCache类是个什么?这里我们点进去看一下。
在这里插入图片描述
关于这个内部类的代码就这么点,从上图我们可以得知这个范围是在-128和127之间,而在这个变量low和high下面还有一个数组的定义,这个数组的内容从上图下方的cache = new Integer[(high - low) + 1];往下看。不难看出这个数组会将上述范围内的数值全部存起来,而我们根据上上图的红圈内容的if判断可以得知如果我们给Integer赋值范围在这个IntegerCache范围之内的话那么会获取这个缓存里已经定义好的其中一个Integer对象返回给你,所以这个范围内的Integer使用==比较的话就是true,否则为false。官方如此做法是为文章上面所说的,在项目加载之初就事先定义好这些数值对象,而后需要用的话就可以节省一定的性能开销了。

该文章仅供参考,如有错误或缺漏欢迎各位指点迷津。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值