两个引用指向内存中的同一个对象但在 java 中独立工作?
Two reference pointing to the same object in memory but works independently in java?
public class StackWithLinkedList<P> {
private Node top = null;
public StackWithLinkedList(){}
public void push(P val){
Node newNode = new Node(val);
if (this.top != null) {
newNode.nextLink = top;
}
this.top = newNode;
}
public void traverse(){
Node currentNode = this.top;
while(currentNode != null){
System.out.println(currentNode.val);
currentNode = currentNode.nextLink;
}
}
private class Node{
Node nextLink;
P val;
public Node(P val){
this.val = val;
}
}
}
看看traverse()中的这段代码,
Node currentNode = this.top;
这里创建了一个节点类型的对象,它指向已经存在的 this.top 节点对象。
所以这意味着,指向内存中同一个对象的两个引用不是吗?
但是当我使用traverse()方法时,两个对象都独立工作,因为遍历后currentNode变为Null,但this.top保持不变,持有所有已推送的节点。
我试过调试,我看到 this.top 与当前节点有相同的内存地址。
最后,
我不明白这是为什么?
您将“对象”和“引用”混为一谈。例如在句子
例如这里:
Look at this code in the traverse(),
Node currentNode = this.top;
here an object of type Node is created that points to the already
existing this.top node object.
这里没有创建 Node
类型的对象(没有 new
,这就是你知道的)。
这里是定义的是Node
类型的(本地)变量。并且存储在 this.top
中的引用也被分配给 currentNode
.
So it means, two references
pointing to the same object in memory isn't it?
是的,这部分又是正确的。
将参考想象成 sheet 的论文。纸张可以是空的(即引用是 null
),也可以写一些地址(即它指向某个对象)。
现在currentNode
是一张纸,上面写的地址恰好和this.top
写的地址一样(有点复杂,因为this
是一张写在上面的纸,如果您查看该地址,您会发现另一张标有 top
的纸上写有一些地址,但这并没有从根本上改变它的工作方式).
在稍后的某个时间点,代码 currentNode
被重新分配(即纸的内容被更改)。首先到一个 不同的 地址(即该地址被草草写下并替换为另一个地址),然后最终是 null
(即您草草写下内容并将其留为“空白”) .
但是仅仅因为你在那张纸上写了并不意味着其他张纸(通过this.top
) 已经改变。没有理由改变它:它们是两张独立的纸,在某一时刻碰巧上面写着相同的东西。
或者换句话说:将新值赋给 currentNode
对currentNode
之前引用的对象完全没有影响.
如果你做了 currentNode.nextLink = null
而不是(基本上) currentNode = null
那么那就不一样了:
currentNode = null
的意思是“去掉写在标有currentNode
的纸上的地址。
currentNode.nextLink = null
的意思是“去currentNode
纸上写的地址,找到一张nextLink
纸,把上面写的地址去掉。
第一个只是改变了引用currentNode
,第二个实际上改变了currentNode
指向的对象。
编辑: 看来您的困惑源于调试视图 currentNode = {StackWithLinkedList$Node@801}
。您似乎将其解释为“currentNode
是对象 {StackWithLinkedList$Node@801}
”,但这不是它的意思。
currentNode
永远不是对象。不可能的。 Java variables/fields 无法容纳对象。那么显示 really 的意思是:currentNode
当前引用 表示为 {StackWithLinkedList$Node@801}
.
的对象
public class StackWithLinkedList<P> {
private Node top = null;
public StackWithLinkedList(){}
public void push(P val){
Node newNode = new Node(val);
if (this.top != null) {
newNode.nextLink = top;
}
this.top = newNode;
}
public void traverse(){
Node currentNode = this.top;
while(currentNode != null){
System.out.println(currentNode.val);
currentNode = currentNode.nextLink;
}
}
private class Node{
Node nextLink;
P val;
public Node(P val){
this.val = val;
}
}
}
看看traverse()中的这段代码,
Node currentNode = this.top;
这里创建了一个节点类型的对象,它指向已经存在的 this.top 节点对象。
所以这意味着,指向内存中同一个对象的两个引用不是吗?
但是当我使用traverse()方法时,两个对象都独立工作,因为遍历后currentNode变为Null,但this.top保持不变,持有所有已推送的节点。
我试过调试,我看到 this.top 与当前节点有相同的内存地址。
最后,
我不明白这是为什么?
您将“对象”和“引用”混为一谈。例如在句子
例如这里:
Look at this code in the traverse(),
Node currentNode = this.top;
here an object of type Node is created that points to the already existing this.top node object.
这里没有创建 Node
类型的对象(没有 new
,这就是你知道的)。
这里是定义的是Node
类型的(本地)变量。并且存储在 this.top
中的引用也被分配给 currentNode
.
So it means, two references pointing to the same object in memory isn't it?
是的,这部分又是正确的。
将参考想象成 sheet 的论文。纸张可以是空的(即引用是 null
),也可以写一些地址(即它指向某个对象)。
现在currentNode
是一张纸,上面写的地址恰好和this.top
写的地址一样(有点复杂,因为this
是一张写在上面的纸,如果您查看该地址,您会发现另一张标有 top
的纸上写有一些地址,但这并没有从根本上改变它的工作方式).
在稍后的某个时间点,代码 currentNode
被重新分配(即纸的内容被更改)。首先到一个 不同的 地址(即该地址被草草写下并替换为另一个地址),然后最终是 null
(即您草草写下内容并将其留为“空白”) .
但是仅仅因为你在那张纸上写了并不意味着其他张纸(通过this.top
) 已经改变。没有理由改变它:它们是两张独立的纸,在某一时刻碰巧上面写着相同的东西。
或者换句话说:将新值赋给 currentNode
对currentNode
之前引用的对象完全没有影响.
如果你做了 currentNode.nextLink = null
而不是(基本上) currentNode = null
那么那就不一样了:
currentNode = null
的意思是“去掉写在标有currentNode
的纸上的地址。currentNode.nextLink = null
的意思是“去currentNode
纸上写的地址,找到一张nextLink
纸,把上面写的地址去掉。
第一个只是改变了引用currentNode
,第二个实际上改变了currentNode
指向的对象。
编辑: 看来您的困惑源于调试视图 currentNode = {StackWithLinkedList$Node@801}
。您似乎将其解释为“currentNode
是对象 {StackWithLinkedList$Node@801}
”,但这不是它的意思。
currentNode
永远不是对象。不可能的。 Java variables/fields 无法容纳对象。那么显示 really 的意思是:currentNode
当前引用 表示为 {StackWithLinkedList$Node@801}
.