Home > Mobile >  Two reference pointing to the same object in memory but works independently in java?
Two reference pointing to the same object in memory but works independently in java?

Time:09-22

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

    }
}

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.
So it means, two references pointing to the same object in memory isn't it?

But when I use the traverse() method, both the object works independently as the currentNode gets to Null after traversing but the this.top remains unchanged, holding all the nodes that have been pushed.

I tried debugging and i saw this.top has the same memory address as the currentNode.

enter image description here

In the end,

enter image description here

I am not able to figure out why is it?

CodePudding user response:

You are conflating "object" and "reference". For example in the sentence

For example here:

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.

No object of type Node is created here (there is no new, that's how you know).

What is defined here is a (local) variable of type Node. And the reference that is stored in this.top is also assigned to currentNode.

So it means, two references pointing to the same object in memory isn't it?

Yes, this part is again correct.

Think of a reference like a sheet of paper. The paper can be empty (i.e. the reference is null) or it can have some address written on it (i.e. it points to some object).

Now currentNode is a piece of paper that happen to have the same address written on it that this.top also has written on it (it's a tiny bit more complicated, because this is a piece of paper written on it and if you look at that address then you'll find some other piece of paper labelled top that has some address written on it, but that doesn't fundamentally change how this works).

At some point later in the code currentNode gets reassigned (i.e. the content of the piece of paper gets changed). First to a different address (i.e. the address scribbled out and replaced with another one) and then eventually with null (i.e. you scribble out the content and leave it "blank").

But just because you wrote on that piece of paper doesn't mean that the other piece of paper (found via this.top) has changed. There is no reason for to it change: they are two independent pieces of paper that at one point happen to have had the same stuff written on them.

Or put differently: assigning a new value to currentNode has absolutely no effect on the object previously referenced by currentNode.

If you had done currentNode.nextLink = null instead of (basically) currentNode = null then that would be different:

  • currentNode = null means "remove the address written on the piece of paper labelled currentNode.
  • currentNode.nextLink = null means "go to the address written on the piece of paper labelled currentNode, there find a piece of paper labelled nextLink and remove the address written on it.

The first one just changes the reference currentNode and the second one actually changes the object pointed to by currentNode.

Edit: it seems your confusion stems from the debugging view where it says currentNode = {StackWithLinkedList$Node@801}. You seem to interpret this as "currentNode is the object {StackWithLinkedList$Node@801}", but that's not what it means.

currentNode is never an object. It can't be. Java variables/fields can't hold objects. So what that display really means is: currentNode currently references the object represented as {StackWithLinkedList$Node@801}.

  • Related