Level: Introductory
Peter Haggar (haggar@us.ibm.com), Senior Software Engineer, IBM
01 Sep 1999
Editor's note: The following articles are excerpts from the book "Practical Java" published by Addison-Wesley. You can order this book at Borders.com.
A common misconception exists that parameters in Java are passed by reference. They are not. Parameters are passed by value. The misconception arises from the fact that all object variables are object references. This leads to some unexpected results if you do not understand exactly what is happening. For example:
import java.awt.Point; class PassByValue { public static void modifyPoint(Point pt, int j) { pt.setLocation(5,5); //1 j = 15; System.out.println("During modifyPoint " + "pt = " + pt + " and j = " + j); } public static void main(String args[]) { Point p = new Point(0,0); //2 int i = 10; System.out.println("Before modifyPoint " + "p = " + p + " and i = " + i); modifyPoint(p, i); //3 System.out.println("After modifyPoint " + "p = " + p + " and i = " + i); } } |
This code creates a Point
object, initialized to (0,0)
, and assigns it to the object reference variable p
at //2. It then assigns the primitive int i
the value 10 . The static modifyPoint
method is then called at //3, passing p
and i
. The modifyPoint
method calls the setLocation
method on the first parameter, pt
, changing its location to (5,5)
. In addition, the second parameter, j
, is assigned the value 15. When the modifyPoint
method returns, method main
prints the values for p
and i
. What is the output of this code and why?
The output of this code is as follows:
Before modifyPoint p = java.awt.Point[x=0,y=0] and i = 10 During modifyPoint pt = java.awt.Point[x=5,y=5] and j = 15 After modifyPoint p = java.awt.Point[x=5,y=5] and i = 10 |
This output shows that the modifyPoint
method changed the Point
object created at //2 but not the int,i
. In main
, i
is assigned the value 10. Parameters are passed by value, therefore, a copy of i
is passed to the modifyPoint
method. This method changes the value of the copy to 15 and returns. The original value, i
in main
, is not changed.
On the other hand, you might think the Point
object created at //2 is unmodified by the modifyPoint
method. After all, Java passes parameters by value. Therefore, when modifyPoint
is called with the Point
object created at //2, a copy is made for the modifyPoint
method to work with. Changes to the Point
object in modifyPoint
are not reflected in main
because there are two different objects. Right? Wrong.
Actually, the modifyPoint
method is working with a copy of a reference to the Point
object, not a copy of the Point
object. Remember that p
is an object reference and that Java passes parameters by value. More specifically, Java passes object references by value. When p
is passed from main
to the modifyPoint
method, a copy of the value of p
, the reference, is passed. Therefore the modifyPoint
method is working with the same object but through the alias, pt
. After entering the modifyPoint
method, but before the execution of the code at //1, the object looks like this:
Figure 1
Therefore, after the code at //1 is executed, the Point
object has changed to (5,5)
. What if you want to disallow changes to the Point
object in methods such as modifyPoint
? There are two solutions for this:
- Pass a clone of the
Point
object to the modifyPoint
method. - Make the
Point
object immutable.
About the author