Register Now

Login

Lost Password

Enter your email to reset your password.

BY Author

What does Java use, call-by-value or call-by-reference?

Call-by-value

In call-by-value, a copy of the actual argument is passed to parameters of method or constructor but not address.

Call-by-reference

In call-by-reference, only the memory address of actual argument is passed to parameters of method or constructor.

Those with the background of C & C++ might seem to be little confused in Java because in Java passing of arguments sometimes feels like call-by-value and sometimes feels like call-by-reference.

Let’s clear that Java always uses call-by-value to pass all arguments.

The only difference in Java’s call-by-value passing is, whether arguments are a primitive type or object reference type.

Now let’s try to solve confusion one by one with small examples.

i) For primitive type

There is no need to confuse with primitive types because in Java all primitive types are passed by call-by-value method.

Example

class TestPrimitiveType 
{
    public void change(int a,int b) 
    {
        a = a*5;
        b = b*5;		
    }

    public static void main(String args[])
    {
        TestPrimitiveType t = new TestPrimitiveType();
        int i = 5;
        int j = 6;
        System.out.println("Before passing");
        System.out.println("i = "+i);
        System.out.println("j = "+j);
        t.change(i, j);
        System.out.println("After Passing");
        System.out.println("i = "+i);
        System.out.println("j = "+j);		
    }
}

Output

Before passing
i = 5
j = 6
After Passing
i = 5
j = 6

In the above program we can clearly see that although changes are made in change() method on the passed values, there is no change in the actual arguments that are passed to the method because these arguments are passed by call-by-value.

Now let’s play with object’s reference

ii) For reference type

Example

class TestObjRefType 
{
    int var1;
    int var2;
	
    public TestObjRefType(int var1, int var2)
    {
        this.var1 = var1;
        this.var2 = var2;
    }
	
    public void change(TestObjRefType obj2)
    {
        obj2.var1 = 2;
        obj2.var2 = 3;
    }

    public static void main(String args[])
    {
        TestObjRefType obj1 = new TestObjRefType(10,20);
        System.out.println("Before Passing");
        System.out.println("obj1.var1 :: "+obj1.var1);
        System.out.println("obj1.var2 :: "+obj1.var2);
        obj1.change(obj1);
        System.out.println("After Passing");
        System.out.println("obj1.var1 :: "+obj1.var1);
        System.out.println("obj1.var2 :: "+obj1.var2);
    }
}

Output

Before Passing
obj1.var1 :: 10
obj1.var2 :: 20
After Passing
obj1.var1 :: 2
obj1.var2 :: 3

In the above program, it can be seen that changes made in change() method are reflected outside the method. That is original arguments are changed.

This happened because reference obj1 of TestObjRefType object is sent to the method change() & same was assigned to the variable obj2 of type TestObjRefType. Now both reference obj1 & obj2 refers to the same object. Therefore changes made through obj2 are reflected in the original object referred by obj1.

Java Programming Language Call by Value and Call by Reference 1

Here it feels like java uses call-by-reference (sending memory address of object) to pass objects, but actually, it does not.

To prove it let’s see one more example.

Example

class TestObjRefType 
{
    int var1;
    int var2;
	
	
    TestObjRefType(int var1,int var2)
    {
        this.var1 = var1;
        this.var2 = var2;
    }
	
    public static void swap(TestObjRefType t1,TestObjRefType t2) 
    {
        TestObjRefType temp;
        temp = t1;
        t1 = t2;
        t2 = temp;
    }
	
    public static void main(String args[])
    {
        TestObjRefType obj1 = new TestObjRefType(4,5);
        TestObjRefType obj2 = new TestObjRefType(10,20);
        System.out.println("Before swaping");
        System.out.println("obj1.var1 :: "+obj1.var1);
        System.out.println("obj1.var2 :: "+obj1.var2);
        System.out.println("obj2.var1 :: "+obj2.var1);
        System.out.println("obj2.var2 :: "+obj2.var2);
        swap(obj1, obj2);
        System.out.println("After swaping");
        System.out.println("obj1.var1 :: "+obj1.var1);
        System.out.println("obj1.var2 :: "+obj1.var2);
        System.out.println("obj2.var1 :: "+obj2.var1);
        System.out.println("obj2.var2 :: "+obj2.var2);		
    }
}

Output

Before swaping
obj1.var1 :: 4
obj1.var2 :: 5
obj2.var1 :: 10
obj2.var2 :: 20
After swaping
obj1.var1 :: 4
obj1.var2 :: 5
obj2.var1 :: 10
obj2.var2 :: 20

In the swap() method of above program, we tried to alter the references obj1 & obj2 of TestObjRefType type objects and expected that after altering their references we’ll get opposite result.
But when we tried to print the values of TestObjRefType type objects they remained same even after altering their references.
This happened because the values that we have sent as object references are passed by call-by-value way and not by call-by-reference (memory address).
When we try to alter the reference to objects in a swap() method, two new references (copy of sent references) are created in stack.
And alteration takes between those two newly created references & not between those two actual references that are sent to swap() method.

For better understanding let’s look at the diagrams shown below:

Before passing references obj1 & obj2 to swap() method two objects of type TestObjRefType are created in heap and two references obj1 & obj2 are created in stack pointing towards objects in a heap as shown below:

Java Programming Language Call by Value and Call by Reference 2

Note

We have assumed addresses of objects in heap as 1000 & 2000 respectively just to make understand the pass-by-value concept in Java. Actually, it is not possible to get the address of objects in Java.
References in Java contain something like an address to point objects present in heap.

After passing object references obj1 & obj2 to swap() method

Java Programming Language Call by Value and Call by Reference 3

After passing obj1 & obj2 to swap() method (shown by the dotted arrow), two new references t1 & t2 are created in stack memory. References t1 & t2 contains the copy of addresses present in obj1 & obj2 (1000 & 2000) respectively.

Therefore now t1 & t2 also starts pointing towards the same objects present in a heap as shown below because they contain the same addresses.

Java Programming Language Call by Value and Call by Reference 4

During swapping

Java Programming Language Call by Value and Call by Reference 5

During swapping addresses of references t1 & t2 are exchanged as shown above.
Therefore henceforth t1 will contain 2000 & t2 will contain 1000 as shown below:

After swapping

Java Programming Language Call by Value and Call by Reference 6

Now we can see that swapping took place in between references t1 & t2 present in method swap() and not between actual references obj1 & obj2.
References obj1 & obj2 still point to the same objects.
From this, we can conclude that in Java always uses call-by-value to pass all arguments and not call-by-reference.

 

Leave a reply