记一次奇怪的空指针问题,窥探自动拆装箱

       昨天下午生产环境跑Job的时候出现空指针问题,本来嘛,空指针对于我们开发人员来说也是见怪不怪了,但空指针是比较头疼的,不是很好排查。说奇怪是因为上午还是好好的:

记一次奇怪的空指针问题,窥探自动拆装箱

报错如下:

记一次奇怪的空指针问题,窥探自动拆装箱

方法调用是这样的:

记一次奇怪的空指针问题,窥探自动拆装箱

类和方法声明:

记一次奇怪的空指针问题,窥探自动拆装箱

       空指针报错在if(fieldEnum.getFieldId() == fieldId)这行,看起来怎么都不会空指针啊,因为所有的枚举都不为空,传过来的参数是基础数据类型,更不可能空了,那为什么会空指针呢?其他人也觉得不可思议,百思不得其解,一般那个文件也不会有人去改,后来有人想到,会不会是哪里把某个枚举设置为空了,然后搜了下setFieldId方法,还真有地方调用,把第一个枚举设空了,而且是我干的:

记一次奇怪的空指针问题,窥探自动拆装箱记一次奇怪的空指针问题,窥探自动拆装箱

       当时是为了处理业务问题这么写,因为这个枚举是全局的,所以别人在调用getFieldEnumById方法时,有个枚举为空,于是产生空指针异常,又因为getFieldEnumById方法只有那里调用,我自己没用,就没发现问题,生产上跑了下我的job,再跑别人的那个job就有问题了,上午是好的是因为我的job上午没有触发。

 

       说到这里,就有疑问了,一个Long和一个long比较,当Long为空时,为什么会空指针呢?想到之前了解到的自动拆箱和装箱:当把一个基础类型赋值给包装器类型,会自动装箱,调用valueOf方法,当把一个包装器类型给基础类型,会自动拆箱,调用value方法,由于对象是空的,调用方法也就空指针了:

debug:

1.Long对象不为空

记一次奇怪的空指针问题,窥探自动拆装箱

记一次奇怪的空指针问题,窥探自动拆装箱

记一次奇怪的空指针问题,窥探自动拆装箱

2.Long对象为空,没有进断点,直接就空指针了

记一次奇怪的空指针问题,窥探自动拆装箱

3.两个都是包装器类型,可以看到,第14行不会对a进行拆箱,所以不会空指针

记一次奇怪的空指针问题,窥探自动拆装箱

希望此文能让你对自动拆装箱有一些认识,我们在以后的开发中多注意。了解原理,赋能自己。