<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Ashwath]]></title><description><![CDATA[This publication helps you and me to learn Java and Backend from the public]]></description><link>https://ashwath.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 09 Sep 2026 02:54:48 GMT</lastBuildDate><atom:link href="https://ashwath.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[
Primitive vs Reference Types in Java: The Mental Model I Wish I Had Earlier]]></title><description><![CDATA[When I started learning Java, I thought I understood the difference between primitive and reference types.
The explanation seemed simple:

Primitives store values. Reference types store references to ]]></description><link>https://ashwath.hashnode.dev/primitive-vs-reference-types-in-java-the-mental-model-i-wish-i-had-earlier</link><guid isPermaLink="true">https://ashwath.hashnode.dev/primitive-vs-reference-types-in-java-the-mental-model-i-wish-i-had-earlier</guid><category><![CDATA[Java]]></category><dc:creator><![CDATA[Ashwath Narayan]]></dc:creator><pubDate>Sat, 29 Aug 2026 15:58:11 GMT</pubDate><content:encoded><![CDATA[<p>When I started learning Java, I thought I understood the difference between primitive and reference types.</p>
<p>The explanation seemed simple:</p>
<blockquote>
<p>Primitives store values. Reference types store references to objects.</p>
</blockquote>
<p>Easy enough.</p>
<p>Then I started asking questions like:</p>
<ul>
<li><p>Where is the actual value stored?</p>
</li>
<li><p>Where is the object stored?</p>
</li>
<li><p>What exactly is stored inside a reference variable?</p>
</li>
<li><p>Why does changing one object sometimes affect another variable?</p>
</li>
<li><p>Why does <code>==</code> behave differently for primitives and objects?</p>
</li>
<li><p>Why do two objects with the same values not necessarily behave as equal?</p>
</li>
<li><p>What exactly happens when I pass an object to a method?</p>
</li>
</ul>
<p>That's when the simple definition stopped being enough.</p>
<p>So I went back to the basics and tried to build a mental model instead of memorizing the difference.</p>
<hr />
<h2>1. I Didn't Understand What a "Reference" Actually Was</h2>
<p>Consider this:</p>
<pre><code class="language-java">int a = 10;
</code></pre>
<p>This one is straightforward.</p>
<p><code>a</code> contains the value <code>10</code>.</p>
<p>But then:</p>
<pre><code class="language-java">User user = new User();
</code></pre>
<p>What does <code>user</code> contain?</p>
<p>Initially, I thought:</p>
<blockquote>
<p><code>user</code> contains the <code>User</code> object.</p>
</blockquote>
<p>But that's not quite the right mental model.</p>
<p>The better model is:</p>
<pre><code class="language-text">user
  |
  | reference
  v
User object
</code></pre>
<p>The variable <code>user</code> holds a <strong>reference to an object</strong>.</p>
<p>Or you can elaborate it as a <code>user</code> variable stores a reference that points to the <code>User</code> Object in memory.</p>
<p>That distinction becomes extremely important once multiple variables point to the same object.</p>
<hr />
<h1>2. What Actually Gets Stored?</h1>
<p>Let's start with primitives.</p>
<pre><code class="language-java">int x = 10;
int y = x;
</code></pre>
<p>Conceptually:</p>
<pre><code class="language-text">x → 10
y → 10
</code></pre>
<p><code>y</code> gets its own copy of the value. Remember the word <strong>Copy</strong> because java is always <strong>Pass By Value</strong>.</p>
<p>So:</p>
<pre><code class="language-java">y = 20;
</code></pre>
<p>results in:</p>
<pre><code class="language-text">x → 10
y → 20
</code></pre>
<p>Changing <code>y</code> doesn't affect <code>x</code>.</p>
<hr />
<p>Now consider an object:</p>
<pre><code class="language-java">public class User{
    String name;
}

User user1 = new User();
User user2 = user1;
</code></pre>
<p>The mental model is different:</p>
<pre><code class="language-text">user1 ─────┐
           │
           ▼
       User object
           ▲
           │
user2 ─────┘
</code></pre>
<p>There is <strong>one object</strong>.</p>
<p>There are <strong>two reference variables</strong> pointing to that same object.</p>
<p>So if we do:</p>
<pre><code class="language-java">user2.setName("John");
</code></pre>
<p>we are modifying the object.</p>
<p>Therefore:</p>
<pre><code class="language-java">user1.getName()
</code></pre>
<p>will also return:</p>
<pre><code class="language-text">John
</code></pre>
<p>because <code>user1</code> and <code>user2</code> refer to the same object.</p>
<p>This was the first important mental shift for me:</p>
<blockquote>
<p><strong>Variables don't necessarily represent independent objects. Multiple reference variables can point to the same object.</strong></p>
</blockquote>
<hr />
<h1>3. The Experiment That Made It Click</h1>
<p>Instead of just reading about it, let's experiment.</p>
<p>Create a simple class:</p>
<pre><code class="language-java">class User {
    String name;
}
</code></pre>
<p>Now:</p>
<pre><code class="language-java">User user1 = new User();
user1.name = "Alice";

User user2 = user1;

user2.name = "Bob";

System.out.println(user1.name);
System.out.println(user2.name);
</code></pre>
<p>Output:</p>
<pre><code class="language-text">Bob
Bob
</code></pre>
<p>Why?</p>
<p>Because there was only one <code>User</code> object.</p>
<pre><code class="language-text">              ┌───────────────┐
user1 ───────►│               │
              │ name = "Bob"   │
user2 ───────►│               │
              └───────────────┘
</code></pre>
<p><code>user2.name = "Bob"</code> didn't change <code>user2</code>.</p>
<p>It changed the <strong>object that both variables refer to</strong>.</p>
<hr />
<h1>4. Primitive vs Reference: The Core Difference</h1>
<p>Now we can finally express the difference more accurately.</p>
<h3>Primitive</h3>
<pre><code class="language-java">int x = 10;
</code></pre>
<p>The variable directly represents a primitive value.</p>
<pre><code class="language-text">x → 10
</code></pre>
<h3>Reference type</h3>
<pre><code class="language-java">User user = new User();
</code></pre>
<p>The variable holds a reference to an object.</p>
<pre><code class="language-text">user → User object
</code></pre>
<p>This distinction explains a lot of Java behavior.</p>
<hr />
<h1>5. What About <code>==</code>?</h1>
<p>This was another place where things became confusing.</p>
<p>Consider primitives:</p>
<pre><code class="language-java">int a = 10;
int b = 10;

System.out.println(a == b);
</code></pre>
<p>Output:</p>
<pre><code class="language-text">true
</code></pre>
<p>Because we're comparing the actual primitive values.</p>
<pre><code class="language-text">10 == 10
</code></pre>
<p>Now consider:</p>
<pre><code class="language-java">User user1 = new User();
User user2 = new User();

System.out.println(user1 == user2);
</code></pre>
<p>Output:</p>
<pre><code class="language-text">false
</code></pre>
<p>Why?</p>
<p>Because these are two different objects.</p>
<pre><code class="language-text">user1 ───► Object A

user2 ───► Object B
</code></pre>
<p>Even if:</p>
<pre><code class="language-java">user1.name = "Alice";
user2.name = "Alice";
</code></pre>
<p>they are still two different objects.</p>
<p><code>==</code> on reference types asks:</p>
<blockquote>
<p><strong>Do these two references refer to the same object?</strong></p>
</blockquote>
<p>So:</p>
<pre><code class="language-java">User user2 = user1;

System.out.println(user1 == user2);
</code></pre>
<p>is:</p>
<pre><code class="language-text">true
</code></pre>
<p>because:</p>
<pre><code class="language-text">user1 ───┐
         ├──► Same object
user2 ───┘
</code></pre>
<hr />
<h1>6. Then Where Does <code>equals()</code> Come In?</h1>
<p>This leads naturally to another Java concept.</p>
<p>Suppose:</p>
<pre><code class="language-java">User user1 = new User();
user1.name = "Alice";

User user2 = new User();
user2.name = "Alice";
</code></pre>
<p>We have:</p>
<pre><code class="language-text">user1 ───► Object A
             name = Alice

user2 ───► Object B
             name = Alice
</code></pre>
<p><code>user1 == user2</code> is <code>false</code>.</p>
<p>But what if our definition of equality is:</p>
<blockquote>
<p>Two users are equal if their names are equal.</p>
</blockquote>
<p>That's what <code>equals()</code> allows us to define.</p>
<p>For example:</p>
<pre><code class="language-java">@Override
public boolean equals(Object obj) {
    // compare relevant fields
}
</code></pre>
<p>So another important mental model emerges:</p>
<pre><code class="language-text">==      → Are these the same object?
equals  → Are these objects logically equal?
</code></pre>
<p>And this is exactly where <code>hashCode()</code> becomes important when using collections such as <code>HashMap</code> and <code>HashSet</code>.</p>
<hr />
<h1>7. What Happens When We Pass Them to Methods?</h1>
<p>This is where the distinction becomes especially useful.<br />Remember Java always passes a copy.</p>
<p>Consider:</p>
<pre><code class="language-java">static void change(int x) {
    x = 20;
}

int a = 10;

change(a);

System.out.println(a);
</code></pre>
<p>Output:</p>
<pre><code class="language-text">10
</code></pre>
<p>Why?</p>
<p>Conceptually:</p>
<pre><code class="language-text">a → 10

change(a)

x → copy of 10
</code></pre>
<p>Changing <code>x</code> doesn't change <code>a</code>.</p>
<hr />
<p>Now:</p>
<pre><code class="language-java">static void change(User user) {
    user.name = "Bob";
}

User user = new User();
user.name = "Alice";

change(user);

System.out.println(user.name);
</code></pre>
<p>Output:</p>
<pre><code class="language-text">Bob
</code></pre>
<p>This sometimes leads people to say:</p>
<blockquote>
<p>"Java passes objects by reference."</p>
</blockquote>
<p>That's <strong>not correct</strong>.</p>
<p>Java is <strong>always pass-by-value</strong>.</p>
<p>The subtle part is:</p>
<blockquote>
<p>For an object, the value being copied is the reference.</p>
</blockquote>
<p>So:</p>
<pre><code class="language-text">main():

user ─────────────► Object
                     name = Alice

                 ↓ pass value (copy of the reference is passed)

method():

user ─────────────► Same Object
                     name = Alice
</code></pre>
<p>Both variables contain references to the same object.</p>
<p>Therefore the method can modify that object.</p>
<p>But the method cannot change the caller's reference variable itself.</p>
<p>For example:</p>
<pre><code class="language-java">static void change(User user) {
    user = new User();
    user.name = "Bob";
}
</code></pre>
<p>After calling:</p>
<pre><code class="language-java">change(user);
</code></pre>
<p>the caller's <code>user</code> still points to the original object.</p>
<p>This happens because the copy of the reference is passed to the method; and that copied reference is made to point to a new object, thus the original reference in the caller remains unchanged.</p>
<p>That's the strongest proof that Java is pass-by-value.</p>
<hr />
<h1>8. The Mental Model I Finally Settled On</h1>
<p>Instead of memorizing a table, I use this:</p>
<h3>Primitive</h3>
<p>Think:</p>
<pre><code class="language-text">VARIABLE
   ↓
 VALUE
</code></pre>
<p>Example:</p>
<pre><code class="language-java">int age = 25;
</code></pre>
<pre><code class="language-text">age → 25
</code></pre>
<h3>Reference</h3>
<p>Think:</p>
<pre><code class="language-text">VARIABLE
   ↓
REFERENCE
   ↓
 OBJECT
</code></pre>
<p>Example:</p>
<pre><code class="language-java">User user = new User();
</code></pre>
<pre><code class="language-text">user → reference → User object
</code></pre>
<p>And multiple variables can hold references to the same object:</p>
<pre><code class="language-text">user1 ─────┐
           ▼
        OBJECT
           ▲
           │
user2 ─────┘
</code></pre>
<p>Once this mental model is clear, several other Java concepts become easier:</p>
<pre><code class="language-text">Primitive vs Reference
        ↓
Assignment
        ↓
== vs equals()
        ↓
Object identity
        ↓
Method arguments
        ↓
Collections
        ↓
equals() + hashCode()
</code></pre>
<p>These aren't isolated topics.</p>
<p>They are connected.</p>
<p>That small change in mental model makes a surprisingly large part of Java easier to understand.</p>
<hr />
<h1>Next things to explore :</h1>
<h2>1. If a reference variable points to a new object, what happens to the old object?</h2>
<p>Consider:</p>
<pre><code class="language-java">User user = new User(); // Object A

user = new User();      // Object B
</code></pre>
<p>Now <code>user</code> points to <strong>Object B</strong>.</p>
<p>But what happens to <strong>Object A</strong>?</p>
<p>If nothing else references Object A, what happens to it?</p>
<h3>Question to explore</h3>
<p><strong>If I lose the reference to an object, who cleans that object from memory?</strong></p>
<hr />
<h2>2. Why does <code>String</code> behave differently from normal objects?</h2>
<p>Consider:</p>
<pre><code class="language-java">String s1 = "Hello";
String s2 = "Hello";

System.out.println(s1 == s2); // true
</code></pre>
<p>Normally, when we create two separate objects, we expect them to have different references.</p>
<p>So how can both <code>s1</code> and <code>s2</code> point to the same <code>String</code> object?</p>
<h3>Question to explore</h3>
<p><strong>Why doesn't Java create a new</strong> <code>String</code> <strong>object every time I write</strong> <code>"Hello"</code><strong>?</strong></p>
<hr />
<h2>3. Where do primitives and objects actually live?</h2>
<p>We often hear things like:</p>
<blockquote>
<p>"Primitives are stored on the stack and objects are stored on the heap."</p>
</blockquote>
<p>But what actually happens inside the JVM when we write:</p>
<pre><code class="language-java">int age = 25;

User user = new User();
</code></pre>
<p>Where is <code>age</code> stored?</p>
<p>Where is the <code>User</code> object stored?</p>
<p>Where is the reference <code>user</code> stored?</p>
<p>And what does the JVM actually do when these lines execute?</p>
<h3>Question to explore</h3>
<p><strong>When I create a variable and an object, what actually happens inside JVM memory?</strong></p>
]]></content:encoded></item></channel></rss>