2

I'm confused as to why the following code doesn't change the data of the Node a:

public class Node{Node next; int data;}
public static void change(Node a)
{
a = a.next;
}

public static void main(String [] args){

Node a = new Node();
Node b = new Node();
a.next = b;
a.data = 1;
b.next = null;
b.data = 2;
change(a);
System.out.print(a.data); //Still 1, why isn't it changed to 2?
}

Since Node is an object, isn't its reference passed by value to the method change? Which means any changes made to the passed in Node should actually change the node?

SKLAK
  • 3,825
  • 9
  • 33
  • 57
  • I'm sure there is a duplicate or two [hundred] .. like http://stackoverflow.com/questions/40480/is-java-pass-by-reference?rq=1 or http://stackoverflow.com/questions/7893492/is-java-really-passing-objects-by-value?rq=1 – user2864740 Oct 20 '13 at 06:25
  • (The above code doesn't work *precisely* because Java is [Call by Value](http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value) - reassignment of parameters *does not* affect the variables/bindings in the caller.) – user2864740 Oct 20 '13 at 06:26
  • I'm trying to understand argument passing in java, not actually trying to achieve some function – SKLAK Oct 20 '13 at 06:26

5 Answers5

3

This is because in Java you call methods via reference-copies.

This means that when you call change(a); Java basically creates a copy of the reference a and this will be the incoming parameter in public static void change(Node a). Inside the method you will then change that copied reference to point somewhere else. And this will have no effect once your method returns.

This exact same code will work though without the method in between.

Do this a = a.next; instead of change(a) and now your a.data will be 2.

noone
  • 19,520
  • 5
  • 61
  • 76
  • "creates a copy of the reference to a " No. `a` *is* a reference (it is a variable of reference type). There cannot be a "reference to `a`". – newacct Oct 21 '13 at 02:07
  • @newacct I think it is quite obvious that I meant a reference to the object in memory which humans refer to as `a`, and not a reference to the reference... but I edited it and removed the "to". – noone Oct 21 '13 at 04:22
0

Your change method does an empty assignment. The variable a is set to the next node but not returned from the method. The change will only be available inside the method scope. You could change that:

public static Node change(Node a)
{
return a.next;
}

And call it with:

a = change(a);
System.out.print(a.data);
Stephan
  • 4,395
  • 3
  • 26
  • 49
0

The operator = change the reference of "a". Use a method "set(Node nodeToCopy)" That will copy all the "nodeToCopy" in the current node.

public class Node{
Node next; 
int data;
public void set(Node Other) {
next = other.next;
data = other.data;
}
}


public static void change(Node a)
{
a.set(a.next);
}

BUT !!! It not that you want to do because, it will break your objects a and b. You have no others solution :

Node a = new Node();
Node b = new Node();
Node i = a;
a.next = b;
a.data = 1;
b.next = null;
b.data = 2;
System.out.print(i.data); //it's 1
i = i.next;
System.out.print(i.data); //it's 2
Pignic
  • 499
  • 3
  • 12
0

With

public static void change(Node a)

a is not an alias but a new variable containing the address of the paramerter passed..

So,

a.data=100;//would change value of the actual Node in main
[NewVariableWithAddressOfa].data=100;

But when you do

a = a.next;
[NewVariableWithAddressOfa]=[NewVariableWithAddressOfa].next;

you are assigning the address of b which won't change the original Node a since as I said earlier a in change method is a new variable!

Anirudha
  • 32,393
  • 7
  • 68
  • 89
-4

Refer to Call by Value for why the assignment to the parameter did not (and will not) alter the variable bindings in the caller:

.. In call-by-value, the argument expression is evaluated, and the resulting value is bound to the corresponding variable in the function .. If the function or procedure is able to assign values to its parameters, only its local copy is assigned - that is, [any variable used as an argument for] a function call is unchanged in the caller's scope when the function returns.

Call-by-value is not a single evaluation strategy, but rather the family of evaluation strategies in which a function's argument is evaluated before being passed to the function ..


Pay attention to the different terms variable, arguments, and parameter above which have been purposefully used. An object that is mutated is, well, changed everywhere - which is consistently describable by Call by [Object] Sharing; this, however, is orthogonal to Call by Value.

Community
  • 1
  • 1
user2864740
  • 60,010
  • 15
  • 145
  • 220
  • i don't know why people downvote without comments. this is an intelligent answer, esp. in its mention of "call by sharing" – necromancer Jul 27 '14 at 06:49