记Integer等值比较的一个坑
一.引言
小伙伴都知道,只要我们写代码,必然就会有BUG的存在。所以解决BUG的过程会伴随程序员的一生,这就是一个无解的常态。在平时的学习和工作过程中,我们需要通过不断地实践和总结,从而形成一套属于自己的解决和处理BUG的成熟方案。之前建哥看到过论坛中有人这样评价一个程序员的水平:只会写代码不会解BUG,只能算是一个业余的程序员;会写代码又能解决一般的BUG,可以称为是一个初级的程序员;会写代码还能解决复杂的BUG,才算是一个高级的软件工程师。这说的尽管不完全正确,但确实有一定的道理,这充分体现了解决BUG的能力对一个软件工程师来说,具有能否在IT行业立足并长久发展下去的重要性。从这点来说建哥还是非常认同的,毕竟解决BUG的过程就是一个开发人员逐步成长并走向辉煌的过程。
既然BUG是开发中无法避免的问题,那我们就没必要在心理上排斥它,而应该学会在学习和工作中和BUG和谐共存的本领。有些BUG出现后会抛出具体的异常信息,而有些BUG则隐藏的比较深,属于是逻辑上的错误,甚至还会出现一些只有通过更换版本或者重启电脑才能得到解决的问题。当然,也有很大一部分BUG是因为编程人员自身粗心所导致的。建哥认为只要保持一颗好的心态和足够的耐心,再结合调试工具、查看源码或从百度上查找等手段,大部分问题都是可以迎刃而解的。而且时间长了,还能在这个过程中不断的积累一些经验,可以更好的让我们去应对未来程序中出现的问题。
下面建哥就给各位小伙伴分享一个我在辅导学员时碰到的奇葩问题,希望能给大家带来一些启示.
二.BUG重现
2.1 相关实体类
2.2 业务代码
三. 执行结果及分析
3.1 执行结果
3.2 结果分析
相信看到这里,很多小伙伴就有疑问了,明明测试数据中是有类别编号为519对应类别信息的,为什么在循环比较判断中没有匹配到呢?
通过IDE调试可以发现,在将1号商品小米手机的类别编号和所有类别的编号进行等值比较时,确实都没有进入到if语句体中。这就很奇怪了,为啥另一个商品又能找到对应的类别对象信息呢???
最后通过查看Integer包装类的源码我们发现,Integer对象在创建时如果值在-128~127范围内【JDK考虑到这个范围内的整数出现的概率比较高】,则会直接从缓存数组中获取对象!也就是说这个范围内,无论代码中使用多少次,获取的都是同一个数据对象,而超出这个范围则每次都是创建新的对象。
四.解决方式
==比较运算符对两个JAVA对象进行相等比较,比较的是这两个对象的地址。根据上面的源码,我们不难得出Integer(12)和Integer(12)在内存中是同一个对象,因此比较的地址是相等的;而Integer(519)和Integer(519)在内存中是两个不同的对象【创建了两次,地址不同】,因此==比较的结果为不等,而我们的这个业务是希望按照它们的值进行是否相等的比较。
解决方法:将==比较运算替换为调用对象的equals方法比较
代码修改后的运行结果:
这样两个商品都匹配到了对应的类别信息【问题解决!!!】
五.总结一下
这个问题如果只是单纯的看代码,我们很难发现问题所在。其实在开发中,我们经常会碰到类似的问题。我们认为某段代码执行的逻辑应该是这样的,但实际上因为我们忽略了底层的一些细小的机制或对原理了解的不透彻,造成程序运行时得到了一个我们所不期望的结果【关键还不能解释为什么会这样】。因此建哥希望大家在平时的学习和工作过程中,对知识点一定要注重原理注重细节,这样才能尽量避免在编写程序时出现一些错误的使用,或者尽可能少的出现一些我们无法解释的逻辑错误。
相关推荐HOT
更多>>分布式锁是什么?有什么作用?
分布式锁是一种用于在分布式系统中实现并发控制的机制。在多个节点或进程之间共享资源时,分布式锁可确保只有一个节点或进程可以访问或修改共享...详情>>
2023-06-15 11:05:38Java中switch条件语句如何使用?
在Java中,switch语句是一种条件语句,用于根据不同的条件值执行不同的代码块。switch语句的语法如下:switch(expression){casevalue1://当expr...详情>>
2023-06-06 16:24:02js获取checkbox是否选中
要检查 JavaScript 复选框是否被选中,可以使用 checked 属性。该属性返回布尔值 true 表示复选框被选中,false 表示未被选中。详情>>
2023-04-21 10:19:04linux查找文件命令
在Linux系统中,可以使用以下命令来查找文件:1.find命令:find命令可以在指定的目录下递归查找文件,可以根据文件名、类型、大小等条件来查找...详情>>
2023-03-14 13:28:14