The Java programming language always uses call by value
This is an excerpt of the book “Core Java, Vol. I – Fundamentals”, that shows (and clarifies) how the Java programming language always uses call by value when passing parameters to a method.
“The Java programming language always uses call by value. That means that the method gets a copy of all parameter values. In particular, the method cannot modify the contents of any parameter variables that are passed to it.
For example, consider the following call:
No matter how the method is implemented, we know that after the method call, the value of percent is still 10.
Let us look a little more closely at this situation. Suppose a method tried to triple the value of a method parameter:
{
x = 3 * x;
}
Let’s call this method:
However, this does not work. After the method call, the value of percent is still 10. Here is what happens:
1. x is initialized with a copy of the value of percent (that is, 10).
2. x is tripled—it is now 30. But percent is still 10.
3. The method ends, and the parameter variable x is no longer in use.
There are, however, two kinds of method parameters:
- Primitive types (numbers, boolean values)
- Object references
You have seen that it is impossible for a method to change a primitive type parameter. The situation is different for object parameters. You can easily implement a method that triples the salary of an employee:
{
x.raiseSalary(200);
}
When you call
then the following happens:
1. x is initialized with a copy of the value of harry, that is, an object reference.
2. The raiseSalary method is applied to that object reference. The Employee object to which both x and harry refer gets its salary raised by 200 percent.
3. The method ends, and the parameter variable x is no longer in use. Of course, the object variable harry continues to refer to the object whose salary was tripled.
As you have seen, it is easily possible —and in fact very common— to implement methods that change the state of an object parameter. The reason is simple. The method gets a
copy of the object reference, and both the original and the copy refer to the same object.
Many programming languages (in particular, C++ and Pascal) have two methods for parameter passing: call by value and call by reference. Some programmers (and unfortunately even some book authors) claim that the Java programming language uses call by reference for objects. However, that is false. Because this is such a common misunderstanding, it is worth examining a counterexample in detail.
Let’s try to write a method that swaps two employee objects:
{
Employee temp = x;
x = y;
y = temp;
}
If the Java programming language used call by reference for objects, this method would work:
swap(a, b);
// does a now refer to Bob, b to Alice?
However, the method does not actually change the object references that are stored in the variables a and b. The x and y parameters of the swap method are initialized with copies
of these references. The method then proceeds to swap these copies.
Employee temp = x;
x = y;
y = temp;
// now x refers to Bob, y to Alice
But ultimately, this is a wasted effort. When the method ends, the parameter variables x and y are abandoned. The original variables a and b still refer to the same objects as they
did before the method call.
This discussion demonstrates that the Java programming language does not use call by reference for objects. Instead, object references are passed by value. Here is a summary of what you can and cannot do with method parameters in the Java programming language:
- A method cannot modify a parameter of primitive type (that is, numbers or boolean values).
- A method can change the state of an object parameter.
- A method cannot make an object parameter refer to a new object.
The program in Listing 4–4 demonstrates these facts. The program first tries to triple the value of a number parameter and does not succeed:
Before: percent=10.0
End of method: x=30.0
After: percent=10.0
It then successfully triples the salary of an employee:
Before: salary=50000.0
End of method: salary=150000.0
After: salary=150000.0
After the method, the state of the object to which harry refers has changed. This is possible because the method modified the state through a copy of the object reference.
Finally, the program demonstrates the failure of the swap method:
Before: a=Alice
Before: b=Bob
End of method: x=Bob
End of method: y=Alice
After: a=Alice
After: b=Bob
As you can see, the parameter variables x and y are swapped, but the variables a and b are not affected.”
This was one of my favorite parts in this book, because of the way it demonstrates these concepts in such a clear way.