空指针会出现在很多语言中,java中空指针异常指的是java.lang.NullPointException,我们都知道对象是保存在内存中的空指针异常中,空是内存地址为空,指针则是指该对象被别的对象指向或引用,当引用时就会爆出异常对象(引用数据类型)如果没有初始化操作就是null,这就是产生空指针异常的根本原因
新建maven项目 exception-traps,增加junit和lombok依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
创建com.lilith.traps.entity包,新增User实体类
@Data
public class User {
public String name;
public String[] books;
public String say(){
System.out.println("say()方法被调用了");
return null;
}
public void readBook(){
System.out.println("readBook()方法被调用了");
}
}
在test包下创建com.lilith.traps.NullPointExceptionTest测试类
public class NullPointExceptionTest {
@Test
public void testCallNullObjMethod(){
User user = null;
user.readBook();
}
}
在测试类中调用testCallNullObjMethod(),控制台打印空指针异常
在NullPointExceptionTest中增加方法testCallNullObjAttr(),测试空指针时调用对象属性
@Test
public void testCallNullObjAttr(){
User user = null;
user.getName();
}
在测试类中执行testCallNullObjAttr(),控制台打印空指针异常
@Test
public void testGetLenOfNullList(){
User user = new User();
System.out.println(user.books.length);
}
testGetLenOfNullList(),控制台打印空指针异常
新增exception包,新增自定义运行时异常类LilithException,并继承RuntimeException
public class LilithException extends RuntimeException {
}
在NullPointExceptionTest测试类中新增方法testThrowNullException()
@Test
public void testThrowNullException(){
LilithException lilithException = null;
throw lilithException;
}
执行testThrowNullException(),抛出空指针异常
在NullPointExceptionTest测试类中新增方法testHandleNullObjectOfMethodReturn()
@Test
public void testHandleNullObjectOfMethodReturn(){
User user = new User();
System.out.println(user.say().concat("Hello"));
}
执行testHandleNullObjectOfMethodReturn(),控制台打印出空指针异常
Java中的8中基本数据类型都会对应一个包装类
自动拆箱引发的空指针:
在test包下新建UnboxingNullPointExceptionTest,新增testAssignValueWhenUnboxing()方法
public class UnboxingNullPointExceptionTest {
@Test
public void testAssignValueWhenUnboxing(){
Long count = null;
long count_ = count;
System.out.println(count_);
}
}
调用testAssignValueWhenUnboxing()方法,控制台打印出空指针报错信息
在UnboxingNullPointExceptionTest测试类中定义一个add()方法,传入两个基本类型的x和y,新建测试方法testInputArgumentsByUnboxing(),在方法中调用add方法,并传入包装类
public static int add(int x, int y){
return x + y;
}
@Test
public void testInputArgumentsByUnboxing(){
Integer x = null;
Integer y = null;
add(x, y);
}
调用testInputArgumentsByUnboxing()方法,控制台打印报错信息如下
在UnboxingNullPointExceptionTest测试类中定义一个compare()方法,传入两个基本类型的x和y,新建测试方法testCompareValueByUnboxing(),在方法中调用compare方法,并传入包装类
public static boolean compare(int x, int y){
return x >= y;
}
@Test
public void testCompareValueByUnboxing(){
Integer x = 1;
Integer y = null;
compare(x, y);
}
执行testCompareValueByUnboxing()方法
拆箱是通过调用包装器类的 xxxValue 方法实现的,也就是说当包装类为空时调用方法就会出现空指针异常
新建测试类StringNullPointExceptionTest,新增测试方法testStringEqual()
public class StringNullPointExceptionTest {
@Test
public void testStringEqual(){
String name = null;
System.out.println(name.equals("stark"));
}
}
执行该方法
控制台打印出空指针异常,这种情况就相当于与空对象调用属性,所以会出现空指针异常
非null字符串与可能为null的字符串使用equals()方法比较时,应该将可能为null的字符串放在equals()方法参数中,才能够进行比较,将最后一句代码替换为
System.out.println("stark".equals(name));
再次执行
控制台正常
在测试类中新增测试类ListNullPointExceptionTest,增加测试方法testHandleNullElementOfList()
public class ListNullPointExceptionTest {
@Test
public void testHandleNullElementOfList(){
User[] userList = new User[5];
for (int i = 0; i < 4; i++) {
userList[i].name = "Mark " + i;
}
}
}
执行该方法
userList[i] 为null,通过.属性的方式赋值会报错空指针
在ListNullPointExceptionTest测试类中新增方法
@Test
public void testAddNullElementToList(){
List<User> userList = new ArrayList<>();
Collection<User> users = null;
userList.addAll(users);
}
执行该方法
控制台出现空指针异常
查看ArrayList的addAll()方法的源码
这里使用了toArray()方法,由于参数本身是null,所以执行会报错