0
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;

这里创建了一个 Node 类型的对象,它指向已经存在的this.top节点对象。
所以这意味着,两个引用指向内存中的同一个对象不是吗?

但是当我使用 traverse() 方法时,两个对象都独立工作,因为 currentNode 在遍历后变为 Null 但 this.top 保持不变,保留所有已推送的节点。

我尝试调试,我看到 this.top 与 currentNode 具有相同的内存地址。

在此处输入图像描述

到底,

在此处输入图像描述

我无法弄清楚为什么会这样?

4

1 回答 1

1

您将“对象”和“参考”混为一谈。例如在句子中

例如这里:

看看traverse()中的这段代码,

Node currentNode = this.top;

这里创建了一个 Node 类型的对象,它指向已经存在的this.top节点对象。

这里没有创建任何类型的对象Node(没有new,这就是你所知道的)。

这里定义的是类型的(局部)变量Node。并且存储在其中的引用this.top也分配给currentNode.

所以这意味着,两个引用指向内存中的同一个对象不是吗?

是的,这部分又是正确的。

把参考想象成一张纸。纸可以是空的(即引用是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 变量/字段不能保存对象。所以该显示的真正含义是: currentNode 当前引用表示为的对象{StackWithLinkedList$Node@801}

于 2021-09-17T14:06:32.223 回答