Call by Value and Call by Reference in Java

Naveen AnamaneniUpdated · 5 min read

"Is Java call by value or call by reference?" is one of the most asked Java interview questions, and one of the most often answered wrongly. The short answer: Java is always call by value. What confuses people is that for objects and arrays, the "value" that gets copied is a reference. Once you see what's copied in each case, every puzzle about it becomes easy.

What Gets Copied

Java copies the value: a number, or a reference
You passThe method receivesCan it change the caller's variable?Can it change the caller's object?
A primitive (int, double...)A copy of the numberNo(no object)
A reference (object, array)A copy of the referenceNoYes, through the copy

Primitives: The Copy Changes, Not the Original

Tax.java▶ Try it
public class Tax {
    static void addTax(int p) {
        p = p * 118 / 100;
        System.out.println("Inside: " + p);
    }
 
    public static void main(String[] args) {
        int price = 100;
        addTax(price);
        System.out.println("Outside: " + price);
    }
}
Output
Inside: 118
Outside: 100

Objects: The Shared Object Changes

Wallet.java▶ Try it
public class Wallet {
    int balance;
 
    static void topUp(Wallet w) {
        w.balance += 200;
    }
 
    static void replace(Wallet w) {
        w = new Wallet();
        w.balance = 9999;
    }
 
    public static void main(String[] args) {
        Wallet mine = new Wallet();
        mine.balance = 500;
        topUp(mine);
        System.out.println("After topUp: " + mine.balance);
        replace(mine);
        System.out.println("After replace: " + mine.balance);
    }
}
Output
After topUp: 700
After replace: 700

How it works

  1. topUp(mine) copies the reference. w and mine point to the same Wallet, so w.balance += 200 changes that object, and main sees 700.
  2. replace(mine) also gets a copy of the reference. Line 9 points that copy at a brand-new Wallet. mine in main still points to the old one, so it still shows 700.

Try it yourself: in replace, add w.balance = 1; before line 9. What does main print now, and why?

Why swap Doesn't Work

Swap.java▶ Try it
public class Swap {
    static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    }
 
    public static void main(String[] args) {
        int x = 1, y = 2;
        swap(x, y);
        System.out.println("x = " + x + ", y = " + y);
    }
}
Output
x = 1, y = 2

The method swaps its copies a and b, which disappear when it returns. In Java, a method can't swap two of the caller's variables. It can swap two elements of an array it's given, because the array object is shared (see "Passing Arrays to Methods and Returning Arrays").

Common Mistakes

Expecting a method to change a primitive variable. Return the new value instead: price = addTax(price);.

Expecting reassigning a parameter to affect the caller. Only changes to the object are visible.

Accidentally changing a caller's object. If a method shouldn't change it, work on a copy, or use an immutable type (see "How to Create an Immutable Class in Java").

Interview Corner

Is Java pass by value or pass by reference?

Always pass by value. For primitives, the value copied is the number itself. For objects and arrays, the value copied is the reference, so the method can change the object the reference points to, but it can't make the caller's variable point to a different object.

Why can't you write a swap method for two int variables in Java?

The method receives copies of the two values. Swapping the copies doesn't affect the caller's variables, and there is no way to pass a reference to a primitive variable. You can swap elements inside an array or fields inside an object, because those are shared.

Practice

  1. Easy: Change addTax to return the new price, and update price in main with the result.
  2. Harder: Write static void swap(int[] a, int i, int j) that swaps two elements of an array, and show that the caller sees the change.

Quick check: Call by value

4 questions
1Is Java pass by value or pass by reference?
2A method receives Wallet w and does w.balance = 0;. Does the caller's wallet change?
3A method does w = new Wallet();. Does the caller's variable now point to the new wallet?
4Why does swap(int a, int b) leave x and y unchanged?

Key Takeaways

Was this tutorial helpful?

Lesson 85 of 482