Are Parameters Passed by Value or By Reference in Java

Many people get confused with the way arguments are passed in Java. Parameters in Java are actually passed-by-value not pass-by-reference. But sometimes we get a feeling its pass-by-reference in case of objects being passed as parameter. Parameter passing is easy to understand for primitive values, but it gets confusing with references. Lets start with passing primitive values as parameter,

class MethodCallExp {
    static void myMethod(int a, int b) {
        a = 10;
        b++;
    }
    public static void main(String[] args) {
        int i = 5;
        int j = 6;
        myMethod(i,j);
        System.out.print("i="+i);
        System.out.print(", j="+j);
    }
}

When we execute this code, the output will be "i=5, j=6". So why didn’t the value of i and j change when we passed them as an argument to myMethod? This is because the value of i and j was copied to a and b. So changing the value of a and b doesn’t effect the value of i and j. So even if i and j were final, the code would work just fine,

class MethodCallExp {
    static void myMethod(int a, int b) {
        a = 10;
        b++;
    }
    public static void main(String[] args) {
        final int i = 5;
        final int j = 6;
        myMethod(i,j);
        System.out.print("i="+i);
        System.out.print(", j="+j);
    }
}

This will again produce the output "i=5, j=6". i and j‘s values will be copied to a and b, so the code would work just fine without any error that you are trying to change value of a final variable. When we change the value of a and b, i and j are not effected. At a first glance someone might think that we are changing the value of final variables i and j but we are not as can be seen from the output.

This whole thing gets a little tricky for object references (you can understand difference between object and reference here). Lets say we have a class like this,

class Person {
    String name;
    int age;
}

Now we’ll pass an instance of the above class and see how passing an object reference as argument works,

class MethodCallExp {
    static void myMethod(Person obj) {
        obj = null;
    }
    public static void main(String[] args) {
        Person p = new Person();
        p.name = "Austin";
        p.age = 35;
        myMethod(p);
        System.out.print("name="+p.name);
        System.out.print(", age="+p.age);
    }
}

So will you get a NullPointerException on line 10? The answer is no. When you pass p as an argument to myMethod, both p and obj start pointing to the same Person object as depicted in the following diagram.

pass-by-reference1When you set obj to null, p still points to the Person object as it was before.

pass-by-reference2So you’ll get "name=Austin, age=35" as the output. If you think about it, this is logical. When p was passed as argument to myMethod, the value in p i.e. the address of Person class’ object was copied to obj. So then both started pointing to the same Person object. When we set obj to null, p wasn’t effected. You can think of p and obj as shortcut to the same text file on your computer. If you change the obj shortcut and point it to a different file (or delete the obj shortcut), p will still point to the original text file. But what happens when you change the state of an object (i.e. change the values of instance fields of the object) in the called method? Lets see an example,

class MethodCallExp {
    static void myMethod(Person obj) {
        obj.name = "Nothing";
        obj.age = 0;
    }
    public static void main(String[] args) {
        Person p = new Person();
        p.name = "Austin";
        p.age = 35;
        myMethod(p);
        System.out.print("name="+p.name);
        System.out.print(", age="+p.age);
    }
}

The output will be "name=nothing, age=0". Some of you might be surprised, some might not? Why did this happen? The answer is simple, since both p and obj were pointing to the same Person class object, so changing the state through any of the references effects the other. We know that p and obj are both references that point to one object, so if we make changes to the actual object, then both the references will reflect the change. If we retake the text file shortcut example, then here p and obj are shortcuts to the same text file. Making changes to the text file through any of the shortcuts will ultimately effect the text file. So after you make changes to the text file from any of the shortcuts, opening the file from the other shortcut will also show you the modified file.

So we can conclude that parameters in Java are passed by value. In case of primitives the value is copied to parameters and in case of references the address of the object is copied to method parameters.

Leave a Comment