Back to Pass-by-Value & References
Q1Question 1 of 2

Is Java pass-by-value or pass-by-reference?

Key Concepts
  • Java is ALWAYS pass-by-value – it copies the value of the variable into the method parameter
  • For primitives: the value itself is copied – changing the parameter does not affect the original
  • For objects: the REFERENCE (address) is copied – both the original and the parameter point to the same object
  • You CAN modify the object's state through the copied reference (same object, two references)
  • You CANNOT make the original reference point to a different object (the copy is independent)
  • Swap test: swapping two object parameters inside a method does NOT swap the originals

Definition

Java is always pass-by-value. For primitives, the value is copied. For objects, the reference (address) is copied – you can modify the object but cannot reassign the original variable.

One rule, two consequences:

  • Primitives: The value is copied. int fee = 50; process(fee); passes a copy of 50. Changing the parameter inside process() does not change fee.
  • Object references: The reference is copied. Account a = new Account(); process(a); passes a copy of the reference. Both the original a and the parameter point to the same object. Modifying the object through the parameter is visible to the caller. But reassigning the parameter to a new object does not affect a.

Passing a primitive is like giving someone a photocopy of a bank slip – they can scribble on their copy, but your original is unchanged. Passing an object reference is like giving someone a copy of a key to a locker – they can open the locker and modify the contents (the object), but giving them a different key (reassigning the parameter) does not change your key.

Understanding the Concepts

Pass-by-value for primitives

JAVA
public static void addFee(int amount) {
    amount += 50;  // modifies the LOCAL copy
    System.out.println("Inside: " + amount);  // 150
}

int amount = 100;
addFee(amount);
System.out.println("Outside: " + amount);  // 100 (unchanged!)

The value 100 is copied into the parameter. The original is unaffected.

Pass-by-value for object references

JAVA
public static void debit(Account account, BigDecimal amount) {
    account.debit(amount);  // modifies the OBJECT (same object, two references)
}

Account rajesh = new Account("SAV2001", new BigDecimal("1000000"));
debit(rajesh, new BigDecimal("50000"));
System.out.println(rajesh.getBalance());  // 950000 (changed! same object)

The reference is copied. Both rajesh and account (the parameter) point to the same heap object. Modifying the object through the parameter is visible to the caller.

Why reassignment does not work

JAVA
public static void replace(Account account) {
    account = new Account("CUR3001", BigDecimal.ZERO);  // reassigns the LOCAL copy
    System.out.println("Inside: " + account.getAccountId());  // CUR3001
}

Account rajesh = new Account("SAV2001", new BigDecimal("1000000"));
replace(rajesh);
System.out.println("Outside: " + rajesh.getAccountId());  // SAV2001 (unchanged!)

Reassigning the parameter to a new object changes only the local copy. The caller's variable still points to the original object.

The swap test (proof that Java is pass-by-value)

JAVA
public static void swap(Account a, Account b) {
    Account temp = a;
    a = b;
    b = temp;
    // a and b are swapped LOCALLY, but the originals are unchanged
}

Account rajesh = new Account("SAV2001", new BigDecimal("1000000"));
Account priya = new Account("CUR3001", new BigDecimal("250000"));
swap(rajesh, priya);
System.out.println(rajesh.getAccountId());  // SAV2001 (not swapped!)
System.out.println(priya.getAccountId());   // CUR3001 (not swapped!)

If Java were pass-by-reference, the swap would work. It does not, proving Java passes copies of the references.

How is this different from C++ pass-by-reference?

In C++, you can declare a parameter as a reference (void swap(Account& a, Account& b)). This gives the method direct access to the caller's variable. Reassigning the parameter reassigns the caller's variable. Java does not have this feature.

What are common mistakes?

  • Saying "objects are passed by reference." Objects are not passed at all. References to objects are passed by value.
  • Expecting swap to work. It does not, because parameters are copies.
  • Confusing "can modify the object" with "pass-by-reference." You can modify the object because both references point to the same object. But you cannot make the caller's variable point elsewhere.

What should a senior engineer know?

  • This is why Java methods return values. Since you cannot modify the caller's variable, you return the new value: BigDecimal newBalance = calculate(balance);
  • Builder and fluent APIs return this to allow chaining: account.withBalance(100).withName("Rajesh"). Each method returns the object, not modifying a parameter.
  • Immutable objects are safe to pass because the method cannot modify their state. This is why String and BigDecimal are immutable.

Visual Overview

DIAGRAM
  Primitive: int amount = 100;
    addFee(amount) → copies 100 into parameter
    parameter += 50 → local copy becomes 150
    amount is still 100 (unchanged)

  Object: Account rajesh = new Account(...);
    debit(rajesh, 50000) → copies the REFERENCE into parameter
    parameter.debit(50000) → modifies the SHARED OBJECT
    rajesh.getBalance() → 950000 (changed via shared reference)

  Reassignment: replace(rajesh)
    parameter = new Account(...) → local copy points to new object
    rajesh still points to original (unchanged)

  Swap: swap(rajesh, priya)
    local copies swapped → originals unchanged
    PROOF: Java is pass-by-value

Key Takeaway

Java is always pass-by-value. For primitives, the actual value is copied. For object references, the reference (memory address) is copied. You can modify the object through the copied reference because both references point to the same heap object. But you cannot make the caller's variable point to a different object by reassigning the parameter.

The swap test proves this: swapping two object parameters inside a method does not swap the caller's variables, because the method only has copies of the references.

One sentence to remember: Java copies the reference, not the object – you can modify the shared object but cannot reassign the caller's variable.

---

Share
Use ← → arrow keys to navigate