前言
大家都知道,对于基本类型(int char float等等),java是传值。对于某个对象,java传递的是什么呢?
疑惑
最近刷 leetcode 删除链表一个节点的时候, 遇到这个问题
看下面代码
public class DeleteNodeLinkedList {
public static void main(String[] args) {
ListNode n0 = new ListNode(10);
ListNode n1 = new ListNode(11);
ListNode n2 = new ListNode(12);
ListNode n3 = new ListNode(13);
n0.next = n1;
n1.next = n2;
n2.next = n3;
System.out.println("before delete in main " + n2);
deleteNode(n2);
System.out.println("after delete in main " + n2);
}
public static void deleteNode(ListNode node) {
if (node == null) {
return;
}
// the last node
if (node.next == null) {
node = null;
}
System.out.println("before assignment in deleteNode " + node);
node = node.next; //这行代码影响很大
System.out.println("after assignment in deleteNode " + node);
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
在方法体
deleteNode(ListNode node)我们用node = node.next;改变了node, 企图删除这个node
输出结果
before delete in main ListNode@27feae0f
before assignment in deleteNode ListNode@27feae0f
after assignment in deleteNode ListNode@41556f4c
after delete in main ListNode@27feae0f
令人遗憾的是, 从方法体内的
before assignment和before assignment可以看出, 在方法体内部, node 是改变了但是在mian函数里面, node 的值
before delete和after delete是一样的
总结与反思
Note
java 是传值的,
对于对象类型,在方法体内部, 也是传递了一个引用的副本
这其实也不难理解, 比如说
isSameTree(r0, r0)我将一个对象作为a参数和b参数传进去, 如果都是同一个引用, 不是混乱了.所以在方法体的内部是引用的副本,上文
node = node.next;是引用的副本改变了,但是真实的引用被没有改变。所以方法里的改变并没有作用到main函数中。
当被传递给函数之后,一个对象至少存在两个引用
我们可以通过引用的副本改变这个实力的成员变量,但是改变这个实例本身只在方法内部起作用。
看下面这个例子
public class DeleteNodeLinkedList {
public static void main(String[] args) {
ListNode n0 = new ListNode(10);
ListNode n1 = new ListNode(11);
ListNode n2 = new ListNode(12);
ListNode n3 = new ListNode(13);
n0.next = n1;
n1.next = n2;
n2.next = n3;
System.out.println("val before delete in main " + n2.val);
deleteNode(n2);
System.out.println("val after delete in main " + n2.val);
}
public static void deleteNode(ListNode node) {
if (node == null) {
return;
}
// the last node
if (node.next == null) {
node = null;
}
System.out.println("val before assignment in deleteNode " + node.val);
node.val = node.next.val; //注意这行代码
System.out.println("val after assignment in deleteNode " + node.val);
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
这个我们在方法体内部改变的是对象成员变量的值, 发现是成功的
改变成员变量 输出
val before delete in main 12
val before assignment in deleteNode 12
val after assignment in deleteNode 13
val after delete in main 13

本文通过LeetCode删除链表节点的问题,深入探讨了Java中对象传递的机制。揭示了方法内部改变对象引用不会影响外部引用,但可以修改对象的属性。
681

被折叠的 条评论
为什么被折叠?



