Call by Value and Call by Reference in Java

In this tutorial, we will understand about call by value and call by reference in Java with the help of examples. In other words, we will understand how argument values are passed to a method in Java.

In Java, all argument values are passed to a method using only call by value (pass by value) mechanism. There is no call by reference (pass by reference) mechanism in Java. So, let’s understand the mechanism “call-by-value” in detail.

Call by Value (Pass by Value) in Java


“Call by value” in Java means that argument’s value is copied and passed to the parameter list of a method. That is, when we call a method with passing argument values to the parameter list, these argument values are copied into the small portion of computer memory. Then, a copy of each value is passed to the parameters of the called method.

When these values are used inside the method either for “read or write operations”, we are actually using the copy of these values, not the original argument values which are unaffected by the operation inside the method.

In other words, the values of the parameters can be modified only inside the scope of the method but such modification inside the method doesn’t affect the original passing argument. When the method returns, the parameters are gone and any changes to them are lost. This whole mechanism is called call by value or pass by value in Java.

Thus, call by value (or pass by value) involves passing a copy of the actual value of a variable to a method. This copy can then be modified within the method, but the original value remains unchanged outside the method. This mechanism prevents accidental alterations to the original data or value.

Let’s understand the concept “pass by value” mechanism by an example program and related diagram.

Example Program based on Call by Value in Java


Let’s take an example program where we will pass an argument value to the parameters of the method using call by value.

Example 1:

package callbyValueExample; 
public class CallbyValue 
{ 
  int change(int b) 
  { 
     ++b; // Changes will be in the local variable only. 
     return b; // return statement
  } 
public static void main(String[] args) 
{ 
// Create an object of class. 
   CallbyValue obj = new CallbyValue(); 
   int a = 20; 
   int x = obj.change(a); // Passing a value to the called method.
     
   System.out.println("Value of a after passing: " +a); 
   System.out.println("Value of x after modifying: " +x); 
 } 
}
Output: 
      Value of a after passing: 20 
      Value of x after modifying: 21

The below figure will illustrate how call by value is working in the above Java program.

Working of call by value mechanism in Java program.

From the above figure, you can see that when we are passing argument value to a method, first, a copy of the value is automatically created into the small portion of memory and then a copy is passed to a method by referenced using parameter name “b”.


As shown in the above figure, the method change() will modify the copy of a, not the original value of “a”. That is, ++b will increment the copy of a. It will not increment the original value of a.

Thus, the value of b that will be returned, will be 21, not 20. Now, this value will be stored in the variable “x” when the return statement from the method will be executed. However, the original value of a will remain at 20 because the modification does not affect the original argument.

Let us consider another example program based on call by value mechanism.

Example 2:

package callbyValueExample; 
public class Test 
{ 
    int x = 20; 
    void modify(int x) 
    { 
        x = x + 200; 
        System.out.println("Value of x after modification: " +x); 
    } 
public static void main(String[] args) 
{ 
    Test t = new Test(); // object creation
    t.modify(t.x); // method calling
    System.out.println("Original value of x: " +t.x); 
 } 
}
Output: 
       Value of x after modification: 220 
       Original value of x: 20

In this example, the modify() method receives a copy of the actual value of variable x. Inside the method, we have added it with 200, and stored the result in a variable x. Then, we have displayed the modified value. However, the original value of variable x remains unaffected outside the method, showcasing how Java’s “call by value” mechanism works.

Call by Reference (Pass by Reference) in Java


In Java “Call by Reference” means passing a reference (i.e. memory address) of the object by value to a method. We know that a variable of class type contains a reference (i.e. address) to an object, not object itself.

When we pass a variable of class type as an argument to a method, actually, a copy of a reference (or memory address) to an object is passed by value to the method, not a copy of the object itself.

This is because Java does not copy the object into the memory. Actually, it copies reference of the object into the memory and passes the copy to the parameters of the called method.

If we change the reference of the object, then the original reference does not get changed because this reference is not original. It’s a copy. For example:

void m1(Emp e); where e is the object reference variable and Emp is the name of a class.

Let’s take an example program to understand call by reference concept in Java.

In the above program, we passed integer values to the parameters of a method. But in a real-time company project, we do not pass primitive values such as int, float, or double values to a method. We pass the reference (address) of the object as a value to the parameters of a method.

Suppose in a real-time project, we are developing a college application in which there are five modules such as Student, Library, Admin, Employee, and College. We will create a class for each module and will pass variables of class type to call the method m1() and m2() in the school class. Let’s see the following example code.

Example 3: 

package callbyValueExample; 
public class Student { } 
public class Library { } 
public class Admin { } 
public class Employee { } 

public class College 
{ 
// Declare an instance method with two objects of Student and Library classes as parameters. 
   void m1(Student s, Library l) // s and l are object reference variables.
   { 
      System.out.println("m1 is calling."); 
   } 
// Similarly, 
   public static void m2(Admin a, Employee ep)
   { 
      System.out.println("m2 is calling"); 
   } 

// Main method.
public static void main(String[] args)
{ 
 // First, create an object of the class college. 
    College c = new College(); 

 // Now, create the object of the classes Student and Library. 
    Student s = new Student(); // (1) 
    Library l = new Library(); // (2) 

 // Pass object reference variables "s" and "l" as argument value to the method m1 for calling m1(). 
    c.m1(s, l); // (3) 

 // Above three lines of code 1, 2, and 3 can be replaced by a single line of code. Both are the same as working. 
    c.m1(new Student(), new Library()); 
    
    Admin a = new Admin(); 
    Employee ep1 = new Employee(); 
    College.m2(a, ep1); // We can pass different Employee type reference variable. Reference Variable name is not important but Employee type is important. So, don't confuse in ep and ep1. 
 
  // Or, 
     College.m2(new Admin(), new Employee()); 
   } 
}
Output: 
       m1 is calling. 
       m1 is calling. 
       m2 is calling 
       m2 is calling

As you can see in the above program, we have passed the reference of objects of different classes as arguments by value to call m1() and m2() methods.


Key Points to Remember:

1. Java passes the arguments both primitives and the copy of object reference by value.

2. Java never passes the object itself.

3. In real-time project, we pass class objects as parameters to method call in Java.

4. Call by value uses copies of data, while call by reference uses memory addresses or references to the actual data.

The concepts of “call by value” and “call by reference” are fundamental in Java programming. Java strictly uses “call by value” mechanism, meaning that it passes a copy of the argument values rather than the original values. This approach ensures that any modification within the method does not affect the original values. Java also passes object references by value.