Many developers get tripped up on this, especially when working with objects. Here's how it really works:
You can change the content 💦 but not the container 🍾.
🧊 Primitives:
Simple and straightforward.
✅ Java copies the value 5 into the method. Changing x doesn’t affect a.
Here the primitive is like the container 🍾 (holder of the value) so it can not be changed (= 5).
📦 Objects:
Still pass-by-value… but here’s the catch.
✅ Java copies the reference (the memory address), not the object itself.
So both the method parameter and the original variable point to the same object in memory. That’s why modifying the object works.
Here sb is the container 🍾 and we modify the content 💦 of this container, so the content is changed ("Hello world").
🔄 But reassigning the reference does NOT affect the original:
Here, Java still passed a copy of the reference. When you did sb = new StringBuilder(...), you only changed the local copy of the reference — not the original.
Here we change the container 🍾 holding its own content 💦 ("hi") but as it is a different container, there are no impact of the original.
🧠 Cheat Metaphor:
You can change the content 💦 (what's inside the bottle), but not the container🍾 (the bottle you were given).
🧪 Summary:
- ✅ Primitives: value copied, safe and predictable.
- ✅ Objects: reference is copied, but it still points to the same object.
- 🚫 You cannot change the original reference by reassigning the parameter inside the method.
If you want a mind-blowing mental image 💥:
You're given the address to someone’s house. You can repaint the walls inside 🖌️, but if you change the GPS coordinate, you're just rerouting yourself—not moving the house!