参考链接:
1. 名词解释
指针:指针中存放的是内存地址。
空:null
空指针:指针不指向任何内存地址(没有初始化分配内存,获得引用)
空指针异常:一个指针不指向任何内存地址,但仍被调用了。
打开 NullPointerException源码,开头就写明出现NullPointerException的原因:
-
Invoking a method from a null object:调用空对象的方法
-
obj.method() // obj对象不存在
-
-
Accessing or modifying a null object’s field:获取或修改空对象的字段
-
obj.setName("cjn") // obj对象不存在
-
-
Taking the length of null, as if it were an array:获取一个空数组的长度
-
array.length // array为null
-
-
Accessing or modifying the slots of null object, as if it were an array:获取或者修改空集合的一个位置上的内容
-
arr[100]=100; // array为null
-
-
Throwing null, as if it were a Throwable value:将null视为Throwable值
-
When you try to synchronize over a null object:当你尝试同步一个空对象
2. 代码测试
测试代码如下:
package exception; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import compare.User; import java.util.Hashtable; import java.util.List; /** * @ClassName NullPointerExceptionTest * @Description 产生空指针异常的原因:在null对象上调用方法或者获取属性 * @Author Jiangnan Cui * @Date 2023/2/13 21:05 * @Version 1.0 */ public class NullPointerExceptionTest { public static void main(String[] args) { stringNullPointerException(); collectionNullPointerException(); packageClassNullPointerException(); } /** * 测试字符串产生的空指针异常 */ public static void stringNullPointerException(){ System.out.println("测试字符串产生的空指针异常"); String str = null; // 1. 字符串内容为null,调用字符串相关方法时会产生空指针异常 // if(!str.isEmpty()){ // System.out.println("str = " + str); // } // 优化:先判断不为null,满足后再调用其所属方法 if(str != null && !str.isEmpty()){ System.out.println("str = " + str); } // 2. 字符串内容为null,进行字符串内容比较时会产生空指针异常 // if(str.equals("test")){ // System.out.println("str = " + str); // } // 优化: // a. 将不为null的字符串内容放在前方 if("test".equals(str)){ System.out.println("str = " + str); } // 2. 使用StrUtil.equals()方法比较,此时str放在前后均可以 // str放在前面 if(StrUtil.equals(str, "test")){ System.out.println("str = " + str); } // str放在后面 if(StrUtil.equals("test", str)){ System.out.println("str = " + str); } } /** * 测试包装类自动拆箱时产生的空指针异常 */ public static void packageClassNullPointerException(){ Integer integer = null; // int number = integer; // System.out.println("number = " + number); // 优化:先判空,再赋值 int number = 0; if(integer != null){ number = integer; } System.out.println("number = " + number); } /** * 测试集合调用时产生的空指针异常 */ public static void collectionNullPointerException(){ // 1. 集合为空时,调用集合相关方法会产生空指针异常 List<String> list = null; // if(list.isEmpty()){ // System.out.println("我是空!"); // } // 优化: // a. 先判断是否是null,不为null时在判空 if(list != null && list.isEmpty()){ System.out.println("我是空!"); } // 集合不为null时,也可以通过.size()方法判断集合是否为空 if(list != null && list.size() > 0){ System.out.println("我是空!"); } // b. 使用工具类判断集合是否为空 if(CollUtil.isEmpty(list)){ System.out.println("我是空!"); } // 2. 向集合中添加元素产生空指针异常 String key = null; String value = null; Hashtable<String,String> hashtable = new Hashtable<>(); // hashtable.put(key,value); // 优化: if(key != null && value != null){ hashtable.put(key, value); } /** * 总结: * 分析:部分集合中不允许设置key或value为null,这类集合主要有:Hashtable、ConcurrentHashMap、ConcurrentSkipListSet、 * ConcurrentLinkedDeque、ConcurrentLinkedQueue、LinkedBlockingDeque、LinkedBlockingQueue、ArrayBlockingQueue、 * PriorityBlockingQueue等。 */ } }
如有错误,欢迎批评指正!