Call by Reference vs Call by Value

There are two ways to call a method – calling by reference and calling by value. While these two approaches can sometimes look the same, passing an array or an object to a method is very different from passing a primitive variable like an int. If you modify an object or array that is a method argument, it will modify the original variable. However, if you modify a primitive method argument, the original variable remains unchanged.

Call by reference

When you pass objects and arrays to methods, you are calling the method by reference. This means that if you change a value in the array, or change a property of the object, then the original variable that you passed to the method will also change.

Consider the following method:

public void setZero(int[] nums) {
for (int i = 0; i < nums.length; i++) {
nums[i] = 0;
}
}

Now, consider this call to setZero:

int[] vals = {1, 2, 3, 4};
setZero(vals);

When we return from setZero, every element in the vals array will be 0. This is because if an array is changed by a method, the original array (vals) is also changed.

Passing objects

Passing objects is also a type of call by reference. Consider the following class:

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) 
    {
        this.name = name;
        this.age = age;
    }

    public void incAge() 
    {
    age++;
    }
}

And consider this outside method:

public void changePerson(Person p) 
{
    p.incAge();
}

Now we create a Person object and call the changePerson method:

Person pers = new Person("Amy", 26);
changePerson(p);

When we return from the changePerson call, pers now has age 27 (since changing the object in the method changed the original object).

However, suppose changePerson looked like this instead:

public void changePerson(Person p) 
{
    p = null;
}

If I now created a Person object and called changePerson:

Person pers = new Person("Amy", 26);
changePerson(p);

Then pers would NOT have the value null after the method call. This is rather confusing (and makes more sense in C++, which uses pointers), but p and pers are two different variables that reference the same object in memory. If I change that object’s age (like in the first version of changePerson), then the age changes for BOTH variables. However, if I set p to null, it just makes p reference null instead of the Person object. pers still references the Person object, so it remains unchanged.

Call by value

When you pass primitive variables (like ints) to a method, whatever changes you make inside the method will not affect the original variable. For example:

public void inc(int x) 
{
    x++;
}

//assume this code is somewhere else in the same class
int num = 4;
inc(num);

Even though the inc method adds one to x, it does not affect the value of num. This is because instead of passing the num variable, only the value is passed. This value (4) is stored in the method argument (x). When I increment x, it does not change num because they are two separate variables.

Just remember that if you pass an int, double, or char and change it inside a method – the change won’t stick. If you change an object or array, the change will stick.