目录
碎碎念:
如下这行报NPE:
排查过程:
解解方案:
小结:
空指针出现的几种情况:
如何从根源避免空指针:
赋值时自动拆箱出现空指针:
1、变量赋值自动拆箱出现的空指针
2、方法传参时自动拆箱引起空指针异常
规避指南:
valueOf()和toString():
心得:
你以为这结束了???肯定不是啊!就在刚刚的截图里面,如果眼睛尖的话,应该也能看出可能存在空指针风险的地方!
使用Optional表达式!
综上
碎碎念:
你知道的,对于初学者或者不是初学者,NPE都是挺让人头疼的问题,在此记录一次NPE问题的排查过程,用来当做耻辱柱,看看是不是总会踩到一个坑里面
如下这行报NPE:
排查过程:
- 你就得思考,为什么获取的时候会报错NPE,因为空对象不能获取东西,所以自然要想到是不是上面在对象创建的时候就是空的;
- 然后就能看到,这个Pair是由两个值拼接而成,其中一个是查询的,所以很合理的猜想,是不是这个查询的值没查到,是null呢?
解解方案:
- 在查询的值外面加上nullToEmpty方法;
- 继续思考,是哪里不能为空呢?
- 先看是不是Pair相关的不能为空;
- 由上面的分析可以推断出,Pair的右值可能为空,因为可能确实没查到,点进去getRight,看到这注释写的是可以为空;
- 由上面的分析可以推断出,Pair的右值可能为空,因为可能确实没查到,点进去getRight,看到这注释写的是可以为空;
- 再看是不是外面包着的Collectors.toMap不接受值为空:
- 点进去:
小结:
虽然知道查询值时有可能因为查不到而返回空,这个时候,为了防止空指针异常就需要进行处理;
空指针出现的几种情况:
1、调用了空对象的实例方法
2、访问了空对象的属性
3、当数组是一个空对象时,取它的长度
4、方法的返回值是 null, 调用方直接去使用
如何从根源避免空指针:
1、使用之前一定要初始化,或检查是否初始化;
2、尽量避免在函数中返回 NULL, 或给出详细的注释;
3、外部传值,除非有明细的说明,否则,一定要判断是否为 NULL。
赋值时自动拆箱出现空指针:
1、变量赋值自动拆箱出现的空指针
Long i = null;
//变量赋值自动拆箱出现的空指针
long j = i;
Long 自动拆箱为 long 实质是调用了 longValue 方法,由于以上的 Long 类型变量值为 null,自动拆箱就会报 NPE。
2、方法传参时自动拆箱引起空指针异常
public static int add(int x, int y) {
return x + y;
}
public static void main(String[] args) {
Integer left = null;
Integer right = null;
//方法传参时自动拆箱引起空指针异常
System.out.println(add(left, right));
}
以上自动拆箱报 NPE,原因在于装箱的值为 null,调用 null 的任何 方法都会报错。
规避指南:
- 基本数据类型优于包装器类型,优先考虑使用基本类型;
- 对于不确定的包装器类型,一定要校验是否为 NULL;
- 基本数据类型比包装器类型更加节省时间与空间;
valueOf()和toString():
- 调用null对象的toString()会抛出空指针异常,使用valueOf()可以获得相同的值,传递一个 null 给 valueOf() 将会返回null。尤其是在那些包装类,像Integer、Float、Double和BigDecimal。
心得:
- 就是代码写得少啊,不然这错误都不应该出现,所以就只能多写代码呗;
你以为这结束了???肯定不是啊!就在刚刚的截图里面,如果眼睛尖的话,应该也能看出可能存在空指针风险的地方!
同样是查询缓存,所以很可能也查不到想要的东西:
并且,写代码不要抱有侥幸心理,墨菲定律……
使用Optional表达式!
改成如下形式即可:
综上:
多写代码……多思考,有问题可以先问ChatGPT!
🤔希望一些顺利,最近感觉有点@#¥%……&*()
本卦:萃。亨,王假有庙。利见大人,亨,利贞。用大牲吉。利有攸往。
变卦:噬嗑。亨。利用狱。