首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Integer引发的生产问题

生产上有一个批量任务,有一天突然不执行了,感觉很怪异,就调查了代码,发现是Integer引起的,具体往下看代码。

Integer引发的生产问题

我们有个Batch的实体类,里面有个Integer的id 成员变量,这个是数据库自增字段,具体代码如下:

batch实体类

一个服务类在执行业务逻辑的时候,会判断传入的id是否和数据库中的Batch的id是否一致,如果一样才执行业务逻辑。具体看看代码:

service服务类

下面做了小测试,发现只有id为1的执行了,128的没有执行,大家都知道== 比较的是对象的内存地址,既然1是相等的,为什么128就不相等了?

其实这里面有两个问题:

1、方法声明是Integer类型,传入一个基本类型怎么也可以?

2,对象的比较==用法问题?

先看第一个问题,第一个问题就是Java 在Java SE5引入的自动装箱和自动拆箱功能。

自动装箱和自动拆箱

装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。基本类型就如:int,char,float,double等,对应的包装类型Interger,Character,Float,Double。

自动装箱和拆箱

我们看看装箱是怎么转换的,先看编译后的代码,我们用javap -c命令。

编译后的代码

我们发现装箱时调用包装类型的valueOf方法,拆箱则调用的是intValue方法。其他包装类也是类似,装箱的方法是valueOf方法,拆箱是xxxValue方法。

第二个问题,为什么Integer的比较可以用==,但是不是所有的值都可以。

Integer的比较

我们知道==比较的对象的内存地址,Integer对象的比较可以用==说明两个对象是同一个。上面也说了,装箱会调用valueOf方法,看看Integer的valueOf方法。

valueOf方法

看到了吧这个方法中有缓存,如果在low和high之间是不会创建新对象的,我们看看填充缓存的代码。

Integer的缓存

从上面的源码看到low为-128和high为127,因此用Integer的valueOf自动装箱或者类型转换时,如果值在[-128,127]之间时,是不会创建对象的,所有==是成立的,如果超过这个范围对象就不是同一个了,用==肯定不成立的。

以上就解释了Integer的比较用==是在一定范围内没问题,可能某一天问题就会出现。所以建议比较对象用equals。

if(Integer == int)

在条件中比如有类似if(Integer == int)的比较,如果包装类型不为null的前提下会转成基本类型再比较,此时会调用对象的xxxValue方法;如果对象为null此时会抛出空指针NullPointerException。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200430A00ET900?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券