Java Methods are “Pass by Value”


Pass by value vs pass by reference in java

We are writing method to accomplish business logic in application. We have to pass the argument to methods for processing. We have to understand how the arguments are passed to methods as “Pass by Value”.  Understanding of this is important as we can populate and set the value of object properties in the method body itself.

Pass by Value : The method parameter values are copied to another variable and then the copied object is passed. Java is pass by value.
Pass by Reference : Reference to the actual parameter is passed to the method. In simple term, actual address of the object is passed to the method. So two references points to the same object, one is actual reference and another one from method as a argument.

Here point to remember is java variables are reference to the objects. For example,

Point pnt = new Point(0,0);    // pnt is variable and it reference the Point object.

Always Java uses the references for non-primitive values  such as objects. It is java internal memory handling and as for as method concern, it is pass by value.  Just copy the value of the parameter and pass to method.

All data is passed by value. The value associated with an object is actually a pointer, called a reference of an object.

For better understanding , let us take real-time example of “Home” object.  Each home(object) has home property document (reference variable). If we take copy of the document (method argument),  it would still refer same home as it copy of document.   So changing the property of home refer by  original document or by copy of the document,  would change actual home . In java, argument values copied and passed to methods. But Java internally employs object reference to refer objects.  So the method argument may look like “Pass by Reference”.  But it is not “Pass by Reference”, it is pass by value as it is copying the value of the argument.

 

pass by value in java

Pass by value

Implementation of Home:

public class PassByValueExample{

public static void main(String[] args) {

Home homeDocument = new Home(40,80,2);
calculateTax(homeDocument);  // copy of reference passed to method.
System.out.println(homeDocument.getPropertyTax());   // It prints value calculated and assigned inside calculateTax() method
extendHome(homeDocument);  //copy of reference passed to method
System.out.println(homeDocument.getPropertyTax());  //  This would not print value assigned inside method  extendHome() method

}
public static void calculateTax(Home documentCopy) {

// The documentCopy is just copy of original Document and it refers the same Home object.
// Any changes in the documentCopy would reflect in actual Home object as it refers the same Home.
documentCopy.setPropertyTax(documentCopy.getBreadth() * documentCopy.getWidth() * documentCopy.getNoofFloors());

}
public static void extendHome( Home documentCopy) {

documentCopy = new Home(200,20,4);   // Now the document has been resigned to refer other new Home();
documentCopy.setPropertyTax(16000);    // Set this would not have any impact on caller Home as now it refer new Home().
// This new reference and home object would be dead after method execution completes.

}

}

class Home{

private int width;
private int breadth;
private int noofFloors;
private int propertyTax;

public Home(int w, int b, int floors) {

width = w; breadth = b; noofFloors = floors;

}
……………
// getter and setter methods

}

Assignment(=) operation on argument would not impact the caller argument values. The changes has been done on object will not visible outside of the method. It is applicable for both primitive and non-primitive variables. By mistake, if we reassign the new object to the argument, new object and reference created and the reference gets new value.  Changing the home object does not impact caller argument value.

Assignment(=) operation on method argument would not impact the caller argument values.

//Generic swap method
public static void swap(Object o1, Object o2){

Object temp = o1;
o1=o2;
o2=temp;

}

“final” method arguments:

Defining the argument as “final” would avoid reassigning the argument inside the method. It is recommended to that mark all the argument as “final” to avoid reassign inside the method.

public static void extendHome(final Home documentCopy) {

documentCopy = new Home(200,20,4); // This would throw compile time error as documentCopy marked as final argument.

…….
}

Primitive argument – Pass by Value:

For primitive argument, the values copied and passed to the method. So changing the value in method body would not have impact in original argument.

//Generic int swap method
public static void swap(int no1, int no2){

int temp = no1;
no1=no2;
no2=temp;

}

public static void main(String[] args) {

int i = 10, j=20;
swap(i,j); // It will not swap the value as it passes copy of the argument.
System.out.println(i + ” : ” + j);

}

Key-points to remember :

  • Java is pass by value.
  • Assignment operation on method argument in method body would not impact caller argument.
  • Inside method we can change instance values of the method argument as caller variable and method argument refers same object.
  • Make method parameter as “final” to avoid assigning of reference by mistake.

 

You may also like