I have the following code. I can't, however, understand it's behavior about pass by value and reference.
class Dog{
String name;
int x=100;
Dog(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
class Demo{
public static void main( String[] args ){
Dog aDog = new Dog("Tom");
foo(aDog);
if (aDog.getName().equals("Tom")) { //true
System.out.println( "Java passes by value."+ aDog.getName());
System.out.println( aDog.x);
} else if (aDog.getName().equals("Taz")) {
System.out.println( "Java passes by reference." );
}
}
public static void foo(Dog d) {
++d.x;
d = new Dog("Taz");
++d.x;
}
}
This will provide output as
Java passes by value.Tom
101
Why is the output 101? I was expecting output 102.
You're incrementing x twice, but on different dogs. Look at this code:
public static void foo(Dog d) {
++d.x;
d = new Dog("Taz");
++d.x;
}
Initially, d refers to the dog with a name of Tom, with x=100. That isn't a copy of the original object - it's a reference to the same object. Java passes the reference by value, which isn't the same as either passing an object by value or passing an object by reference. It's important to understand that the value of aDog in main isn't a Dog object - it's a reference to a Dog object. The value of that reference is passed, by value, to your foo method... so the initial value of d is the same as the value of aDog. Further changes to the d variable itself (rather than the object its value refers to) do not change the aDog variable.
So, looking at the rest of foo:
++d.x, d refers to the dog with a name of Tom, with x=101.d = new Dog("Taz"), d refers to a dog with a name of Taz, with x=100.++d.x, d refers to the dog with a name of Taz, with x=101.The calling code only ever knows about the dog with a name of Tom, so it prints out Tom 101.
You increment x once, on the dog that was given to the method ("Tom").
Then you create a new dog, called Taz.
You then increment x for that second dog. It won't affect the original one, and both dogs will be at 101.
As for why the calling method still refers to "Tom", even though you changed your local variable to point at "Taz": That's because a local variable is just that: local to the place it is used. The caller does not care about what you do with it later, its own variable will still point at "Tom".
Because Java does not support pass-by-reference or "out parameters", there is nothing the called function can do to change the value of variables in the calling function.
But note that objects are not stored in variables. Only a pointer to them is stored there. The actual object instance itself is in a shared location (the program heap memory). So the called method can indeed change the object. But it cannot assign a different object into the calling function.
Takeaway: Make your local variables final, especially method parameters. Then you cannot reuse the same variable for two different things, and the code becomes less confusing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With