防范链表 NullPointerException 的关键是每次访问节点属性或方法前必须先判断节点是否为 null,尤其在循环、递归及空链表等边界条件下;遍历需先判 cur != null 再访问字段,双指针要同步判空,高频操作应封装 null 安全逻辑。

链表操作中出现 NullPointerException,绝大多数是因为对 null 节点执行了取值、赋值或方法调用(如 next、val、.equals() 等)。防范关键在于:**每次访问节点属性或方法前,明确判断该节点是否为 null;尤其在循环、递归、边界条件(头/尾/空链表)中不能假设节点一定存在。**
遍历链表时避免直接访问 next 或 val
常见错误是写成 while (cur.next != null) 后直接用 cur.next.val,但若 cur 本身为 null,就会在进入循环前就抛异常。
- 安全写法:先判
cur != null,再访问其字段 - 示例(找倒数第 k 个节点):
❌ 错误:while (fast.next != null) { fast = fast.next; }(若fast == null,直接 NPE)
✅ 正确:while (fast != null && fast.next != null) { fast = fast.next; }
处理头节点为空的边界情况
空链表(head == null)是最易被忽略的场景。任何涉及 head 的操作(插入、删除、反转、合并)都应优先检查。
- 插入到空链表?先判断
if (head == null),再决定是否新建节点并赋给head - 删除头节点?不能直接写
head = head.next,需先确认head != null - 递归函数入口?第一行加
if (head == null) return null;
修改指针前确保前置节点非 null
链表重构类操作(如反转、分组翻转、删除重复节点)常需临时保存 next、调整 cur.next 指向。一旦 cur 是 null,cur.next 就非法。
- 反转链表循环体中:
ListNode next = cur.next;→ 必须保证cur != null才能执行
建议循环条件写为while (cur != null),并在循环内第一句做安全提取 - 双指针协同移动时(如快慢指针),两个指针要同步判空:
if (slow != null && fast != null && fast.next != null)
工具方法封装 null 安全逻辑
高频操作可封装为带 null 判断的辅助方法,减少重复疏漏。
- 例如:
getNodeAt(head, index)内部先判head == null,再遍历,越界时返回null而非抛异常 - 比较两节点值:
Objects.equals(a?.val, b?.val)(Java 7+)或手动判空:if (a != null && b != null && a.val == b.val)

















