Chapter 01 到底什么是空指针异常?
空指针会出现在很多语言中,java中空指针异常指的是java.lang.NullPointException,我们都知道对象是保存在内存中的空指针异常中,空是内存地址为空,指针则是指该对象被别的对象指向或引用,当引用时就会爆出异常对象(引用数据类型)如果没有初始化操作就是null,这就是产生空指针异常的根本原因
Section 01 常见空指针异常
模拟空指针异常的场景
新建一个maven项目
新增package com.citi.npe
创建NpeApplication,新增main方法
public class NpeApplication {
public static void main(String[] args) {
}
}
复制代码
创建entity包,新增User实体类
public class User {
public String name;
public String[] books;
public void say(){
System.out.println("This is say method");
}
public String readBook(){
System.out.println("This is read book method");
return null;
}
}
复制代码
现象1:访问了空对象的属性
public static void callNullObjectAttribute(){
User user = null;
System.out.println(user.name);
}
复制代码
在main方法中调用callNullObjectAttribute(),控制台打印空指针异常
现象2:调用了空对象的实例方法
public static void callNullObjectMethod(){
User user = null;
user.say();
}
复制代码
在main方法中调用callNullObjectMethod(),控制台打印空指针异常
现象3:当数组是一个空对象的时候,取他的长度
public static void getLenFromNullArray(){
User user = null;
System.out.println(user.books.length);
}
复制代码
在main方法中调用getLenFromNullArray(),控制台打印空指针异常
现象4:抛出空的运行时异常
新增exception包,新增CustException自定义运行时异常类,并继承RuntimeException
public static void throwNullException(){
CustException custException = null;
throw custException;
}
复制代码
在main方法中调用throwNullException(),抛出空指针异常
现象5: 对方法返回的空对象进行操作
public static void opNullObjReturnFromMethod(){
User user = null;
System.out.println(user.readBook().contains("book"));
}
复制代码
在main方法中调用opNullObjReturnFromMethod(),控制台打印出空指针异常
如何避免空指针异常
- 使用对象之前一定要进行初始化,或者对是否初始化进行校验
- 不要设置函数返回值为null
- 针对接收的对象一定要进行判断
Section 02 赋值自动拆箱空指针异常
赋值时自动拆箱出现空指针异常
自动拆箱引发的空指针
- 变量赋值自动拆箱引发空指针
- 方法传递参数自动拆箱引发空指针
在npe包下新建UnboxingNpeApplication
public class UnboxingNpeApplication {
public static void main(String[] args) {
}
}
复制代码
变量赋值时自动拆箱的空指针异常
public static void assignValueByUnboxing(){
Integer i = null;
int i_01 = i;
System.out.println(i_01);
}
复制代码
main方法中调用assignValueByUnboxing(),控制台打印出空指针报错信息
方法传参时自动拆箱空指针异常
public static void passArguByUnboxing(){
Integer x = null;
Integer y = null;
add(x,y);
}
public static int add(int x, int y){
return x + y;
}
复制代码
main方法中调用passArguByUnboxing(),控制台打印报错信息如下
规避空指针异常的建议
- 基本数据类型和引用数据类型,优先考虑基本数据类型
- 对于不确定的包装器类型进行判断校验
- 对于值为null的包装起赋值为0
Section 03 - 集合出现空指针的情况
新增CollectionNpeApplication,并添加main方法
字符串使用equals()方法比较时空指针
public static boolean isEqualStringAndNull(String x, String y){
return x.equals(y);
}
复制代码
在main方法中调用
public static void main(String[] args) {
// 常量.equals(变量)
boolean isEqual = isEqualStringAndNull("abc",null);
System.out.println(""abc"与null比较:" + isEqual);
boolean isEqual1 = isEqualStringAndNull(null,"abc");
System.out.println("null与"abc"比较:" + isEqual1);
}
复制代码
控制台打印如下null.equals("abc")爆了空指针报错,字符串与null使用equals()方法比较时,变量放在equals()方法参数中,方式变量为null时报空指针异常
操作对象对象数组中的空对象时空指针
在测试类中新增方法
public static void emptyObjectArray(){
User[] userList = new User[5];
for (int i = 1; i <= userList.length; i++) {
// userList[i] 为null,自然不能通过.属性的方式赋值
userList[i].name = "stark no." + i;
}
}
复制代码
执行该静态方法,userList[i] 为null,通过.属性的方式赋值也会报错空指针
List,ArrayList执行addAll(null)时空指针
查看ArrayList的addAll()方法的源码
这里使用了toArray()方法,由于参数本身是null,所以执行会报错




近期评论