理论照进现实——工作中遇到的Integer与int相关的bug
最近在测试系统接口的时候,发现有个校验数量的方法没通过。于是我很自信的给数据提供方把验证错误的消息发过去了,数据提供方验证了一上午的数据,告诉我数据确定没有错。我就想以前的数据校验也通过了,唯独这次不行,一定是数据提供方的问题,我打了断点一步一步调试,试图找到他们数据对不上的罪证,直到经过一个判断的时候,我发现里面不相等的逻辑执行了,但是看判断两边的值又是相等的,打印出来也是相等的。终于我想到了Integer类型计较相关的知识。
首先要分析的是为什么之前是对的,这就跟两个Integer类型比较相关了,因为以前数据最多也就到几十的比较,这次数据到了几百的比较,Integer类型在-128~127是会用值进行比较,而超过了用双等于比较就会比较地址,地址不同,则判断为false。其次有的地方用的list的size方法而size默认是int类型的,Integer在与int类型比较会自动拆箱用值比较因此没有出错。
知识点:
Integer 和 int的区别
int是基本数据类型,变量中直接存放数值,变量初始化时值是0Integer是引用数据类型,变量中存放的是该对象的引用,变量初始化时值时null
Integer是int类型的包装类,将int封装成Integer,符合java面向对象的特性,可以使用各种方法比如和其他数据类型间的转换
Integer和int的深入对比:
两个通过new生成的Integer对象,由于在堆中地址不同,所以永远不相等
int和Integer比较时,只要数值相等,结果就相等,因为包装类和基本数据类型比较时,会自动拆箱,将Integer转化为int
通过new生成的Integer对象和非通过new生成的Integer对象相比较时,由于前者存放在堆中,后者存放在Java常量池中,所以永远不相等
两个非通过new生成的Integer对象比较时,如果两个变量的数值相等且在-128到127之间,结果就相等。这是因为给Integer对象赋一个int值,java在编译时,会自动调用静态方法valueOf(),根据java api中对Integer类型的valueOf的定义,对于-128到127之间的整数,会进行缓存,如果下次再赋相同的值会直接从缓存中取,即享元模式