为何设置链表节点next为null不会影响其指向的节点?
我正在尝试用Java反转单链表,但对反转过程中的引用工作机制存在困惑。具体来说,我不理解为何将一个节点的next指针设为null,不会对它原本指向的节点(即下一个节点)产生影响。
示例场景
初始链表结构:
1 -> 2 -> 3 -> null
我使用以下代码反转链表:
class ListNode { int val; ListNode next; ListNode(int val) { this.val = val; } } class Solution { public ListNode reverseList(ListNode head) { ListNode prev = null; ListNode temp = head; while (temp != null) { ListNode front = temp.next; // 保存下一个节点(初始时为节点2) temp.next = prev; // 将node1.next设为null(断开node1与node2的连接) prev = temp; temp = front; } return prev; } }
我的预期
初始时node1的next指向node2,当执行node1.next = null时,我认为node2会受到影响——要么它的next指针变为null,要么node2本身变为null。
实际情况
执行node1.next = null后,链表变为:
1 -> null 2 -> 3 -> null
node2未受任何影响,它的next指针仍指向node3,自身也未被置空。
核心困惑
为何设置node1.next = null时,node2不会变为null?我原本以为断开node1和node2的连接会对node2产生影响,但实际并没有。
结合front指针的例子:
当执行front = temp.next时,保存了对下一个节点的引用(第一次循环中,因为temp是node1,所以front指向node2),这是有效的。但执行temp.next = prev(即node1.next = null)时,只有node1的next指针被更新,并未影响node2,尽管之前node1的next指向node2。
我不理解的是:
为何设置node1.next = null不会影响node1.next原本指向的node2?既然front能通过保存temp.next正确持有node2的引用,那为何设置node1.next = null时,node2本身不会被置空(或其next指针被修改)?
解答
要搞懂这个问题,得先明确Java里引用和对象的本质区别:
- node1、node2这类变量是引用,它们只是指向内存中实际存在的
ListNode对象的"指针"。 - node1的
next是node1对象的一个字段,本质也是一个引用,它的作用是指向另一个ListNode对象(也就是node2)。
当你执行node1.next = null时,你只是修改了node1对象内部的next引用字段——让它从指向node2对象改成指向null。整个过程中,你根本没有触碰过node2对象本身,自然不会修改node2的任何属性(包括它的next指针)。
用现实场景类比:你手里有一张纸条(node1),上面写着朋友家的地址(node2的内存地址)。当你把纸条上的地址擦掉换成空白(node1.next = null),这完全不会影响你朋友的家(node2对象),朋友家的门牌号(node2的next)还是原来的样子。而front = temp.next就相当于你提前复印了一张写着朋友家地址的纸条,就算原纸条的地址被擦掉,复印件上的地址依然有效,你还是能找到朋友家。
另外,Java里对象只有在没有任何引用指向它时,才会被垃圾回收机制处理。这里node2还被front引用着,所以它既不会被置空,也不会被销毁。
内容的提问来源于stack exchange,提问作者Samrudh S

