未将对象引用到对象的实例

  前天改了个bug,是初学者很常见的一个bug,“未将对象引用到对象的实例”。

      起初看到这个bug的时候,我不屑一顾,无非就是后端使用某对象的时候,判断下null再使用就行了,因此断点调试我也是这么观测的。随手一改,调试到指定位置看到抛异常的地方,就加上if-else了,甚至懒得再继续调试,问题就在这里。

      然鹅,鬼使神差的突然想继续调试下,这一下不得了!断点往下继续走,在其他的地方也抛异常了,依然是对象为null导致的。 

      什么对象呢?姑且称之为userInfo,后端接口里使用的时候直接userInfo.UserId访问了,如果userInfo = null,就会抛标题中的这个问题。一般的,我们系统是需要登录的,userInfo正常不会为null,但是巧就巧在,当换个身份以及入口进行登录时,这个userInfo就有可能为null,另外一个身份的用户信息并不是记在这个对象里的(并不是什么都往这个对象里存,代码里的变量也不是叫userInfo,也不一定是存用户信息,只是说,有类似这么个东西,这里不过多探讨)。

      那么怎么处理呢,最开始想的自然是该接口每个涉及的地方,都判断下再使用,避免报这个“低级”错误。

      经过对代码的阅读,发现其实并不好改,并不是每个地方加上if-else就完事的,if里不为空可以走逻辑,但是else没数据,可是不行的。因此在加完第一个地方的判断后,我就发现后续一些用到这个对象的地方,对象本身不能为null,否则逻辑无法走通。即便改了,也并不一定是对的(记住这句话)。

      所以进一步思考,为什么这个对象为null?以前怎么没报这个错误?这个方法哪些地方在调用,是否调用的地方不同,导致这里有一些场景没有考虑?或者说,在某些场景里,这个对象是否也应该赋值一下?于是乎,我看了下这个对象的赋值逻辑,果然在场景2中,该对象没有赋值。那么是不是在场景2里对userInfo赋值一下就完事了呢?并不是。

      首先我排查了场景1和场景2,最近的改动不涉及对userInfo的赋值,所以很明显并不是针对赋值改出来的bug,场景1赋值,场景2不赋值,以前就是这样,既然以前就是这样,那以前怎么不报错?以前不走这里?嗯?——对,场景2的时候,不走这里!我一下子就转过来了。

      请求接口的时候这个对象确实为null,导致报错,那么,为什么场景2的时候,要请求这个接口呢?这,才是关键!

      经过对业务的理解和,场景2是无需请求这个接口的,这里请求了,很明显跟最近的改动有关,最后发现是某个公共JS修改导致。解决办法就是在JS里做下兼容,修复该页面的bug,使其和以前保持一致,场景2时不请求接口,这样也就不会有“未将对象引用到对象的实例”这个错误了。

 

  初看这个问题是不是很简单,从编程入门,到多年开发,其实很难绕开这个, 尤其一些项目运作了很久,代码成千上万行,很难保证修改某个地方的时候不会影响其他地方,从而导致一些奇怪的,亦或低级的bug。不过这里要说的并不是这个问题的难易,而是当我们改一个bug的时候,先想想,是什么bug,为什么要改,要怎么改,改哪里,说简单点就是,抛异常的地方并不一定就是要改的地方,很可能要改的地方在这段代码更前面。很多时候,要从源头解决问题。

posted @   顾星河  阅读(123)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示