Call by Value and Call by Reference in Java
"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
| You pass | The method receives | Can it change the caller's variable? | Can it change the caller's object? |
|---|---|---|---|
A primitive (int, double...) | A copy of the number | No | (no object) |
| A reference (object, array) | A copy of the reference | No | Yes, through the copy |
Primitives: The Copy Changes, Not the Original
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);
}
}Inside: 118
Outside: 100Objects: The Shared Object Changes
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);
}
}After topUp: 700
After replace: 700How it works
topUp(mine)copies the reference.wandminepoint to the sameWallet, sow.balance += 200changes that object, andmainsees 700.replace(mine)also gets a copy of the reference. Line 9 points that copy at a brand-newWallet.mineinmainstill 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
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);
}
}x = 1, y = 2The 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
- Easy: Change
addTaxto return the new price, and updatepriceinmainwith the result. - 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.
Key Takeaways
Was this tutorial helpful?