链表传入函数的行为解析:为何按引用传递后节点未如预期改变?
链表作为函数参数的传递逻辑详解
我完全懂你的困惑——很多人刚接触对象传递时都会误以为是"引用传递",觉得函数里改了参数,外部变量就会跟着变,但其实这里的核心是Java(以及很多类似面向对象语言)的参数传递是「值传递」,传递的是对象引用的副本,不是引用本身。
咱们结合你的场景拆解一下:
假设你的代码大概是这样的(根据输出推测):
class Node { int val; Node next; Node(int val) { this.val = val; } Node(int val, Node next) { this.val = val; this.next = next; } @Override public String toString() { return next == null ? "Node(" + val + ")" : "Node(" + val + ", " + next + ")"; } } public class Main { static void m(Node lnk) { // 你在这里执行了类似 lnk = new Node(3); 的操作 lnk = new Node(3); System.out.println(lnk); // 输出 Node(3) } public static void main(String[] args) { Node lnk = new Node(1, new Node(3)); m(lnk); System.out.println(lnk); // 输出 Node(1, Node(3)) } }
关键逻辑拆解:
- 外部的
lnk变量,本质上是一个指向Node(1)对象的内存地址(比如假设是0x123)。 - 当调用
m(lnk)时,Java会把这个地址0x123复制一份,传给函数内部的参数lnk(注意:这是两个不同的变量,只是暂时存了同一个地址)。 - 当你在函数里执行
lnk = new Node(3)时,你只是把函数内部的那个参数变量的值改成了新Node(3)的地址(比如0x456),但外部的lnk变量依然保存着原来的0x123,指向原来的Node(1)对象。
那什么时候外部变量会跟着变?
如果你的函数里不是重新给参数赋值,而是修改参数指向的对象的内部属性,比如:
static void m(Node lnk) { lnk.next = new Node(5); // 修改原有Node的next属性 System.out.println(lnk); // 输出 Node(1, Node(5)) }
这时候外部的lnk输出也会变成Node(1, Node(5))——因为函数内外的两个变量都指向同一个Node(1)对象,修改对象的内容会影响所有指向它的引用。
简单总结:
- 如果你改的是参数变量本身(重新赋值),只会影响函数内部的副本,外部变量不受影响。
- 如果你改的是参数指向的对象的内容,外部变量因为指向同一个对象,所以会看到变化。
内容的提问来源于stack exchange,提问作者BeepBoop
相关产品推荐
相关产品推荐

