Skip to main content

🀯 “Why Integer a = 128; Integer b = 128; Broke My Brain”

🎬 Intro — “I Thought I Knew ==… Until Java Proved Me Wrong”

I was casually writing:

Integer a = 128;
Integer b = 128;
System.out.println(a == b); // Output: false ❌

…and confidently told myself:

“Yeah, that’s definitely true.”

πŸ’₯ WRONG! Output: false


I was like… 🧍‍♂️ “Hello? Java, are you okay?”

Let's break this down, and I’ll show you what I learned — in my usual style: with humor, diagrams, dumb-but-smart questions, and gotchas!

πŸ§ͺ 1. Code Examples That Confused Me

✅ Primitive Comparison Works

int a = 128;
int b = 128;
System.out.println(a == b); // true ✅

➡️ Simple! Both values are 128, both stored in stack. Done.

❌ Object Comparison Fails?

Integer a = 128;
Integer b = 128;
System.out.println(a == b); // false ❌

➡️ Wait, same values, but still false?

✅ Mixed (Object + Primitive)

Integer a = 128;
int b = 128;
System.out.println(a == b); // true ✅

➡️ What? Now it works again?


🧠 2. The Root Cause: Memory Layout (With Diagram!)

Let’s see how these are stored in memory.

πŸ“¦ Primitive Example:


int a = 128;
int b = 128;

πŸ“ Stack Memory:
+--------+       +--------+
|   a    | 128   |   b    | 128
+--------+       +--------+

✅ a == b → compares 128 == 128 → ✅ true

πŸ“¦ Object Example:


Integer a = 128;
Integer b = 128;


πŸ“ Stack                       🧠 Heap
+--------+                   +-----------------+
|   a    | ─────┐            | Integer@0xABC   |
+--------+      └──────▶     | value = 128     |
                             +-----------------+

+--------+                   +-----------------+
|   b    | ─────┐            | Integer@0xDEF   |
+--------+      └──────▶     | value = 128     |
                             +-----------------+

❌ a == b → compares 0xABC != 0xDEF → false


🧠 3. So What Does == Actually Do?

Case What == Compares Output
int == int Primitive values ✅ true
Integer == Integer Object references (memory) ❌ false
Integer == int Auto-unboxed to primitive ✅ true

🧠 Java is smart! It decides based on types at compile time:

  • Primitives? → Compare values
  • Objects? → Compare reference (i.e., memory address)
  • Mix? → Unbox object → Compare values

🧡 4. What About Small Numbers?


Integer a = 127;
Integer b = 127;
System.out.println(a == b); // ✅ true

😲 Surprise! This one is true. Why?


πŸ”₯ 5. Behind-the-Scenes: Integer Caching!


Integer a = 127;
Integer b = 127;

Java caches values from -128 to 127. These are reused from a common pool:


IntegerCache:
-128 → memory@100
...
127  → memory@300

So a == b → both point to memory@300 → ✅ true


🚧 6. Gotchas & Surprises

Integer a = 127;
Integer b = 127;
System.out.println(a == b); // ✅ true
Integer x = 128;
Integer y = 128;
System.out.println(x == y); // false ❌

✅ Because 128 is outside the cache range, Java creates new objects.

Want to increase the cache?

-Djava.lang.Integer.IntegerCache.high=256


🧠 Where is the Integer Cache (-128 to 127) Stored — Stack or Heap?

✅ Answer:
πŸ‘‰ In the Heap — specifically as part of the IntegerCache class inside the Integer class.

πŸ“¦ What exactly happens?

When you write:


Integer a = 100;
Integer b = 100;
System.out.println(a == b); // ✅ true

Java does not create a new object every time for small values (from -128 to 127). Instead, it returns a pre-cached object stored in a static array.

πŸ” Internally:

private static class IntegerCache {
    static final Integer cache[] = new Integer[-(-128) + 127 + 1];

    static {
        for (int i = 0; i < cache.length; i++)
            cache[i] = new Integer(i - 128);
    }
}

  • This static cache[] is initialized once.
  • These objects live in the heap memory (because they're part of class static fields).
  • So when you do Integer.valueOf(100), Java gives you a reference to cache[100 + 128].

πŸ’Ύ Memory Layout:

Stack (Thread Local)
┌────────────┐
│ Integer a  │──┐
└────────────┘  │
┌────────────┐  │
│ Integer b  │──┘
└────────────┘

Heap (Shared)
┌────────────────────────┐
│ IntegerCache.cache[]   │
│ ┌────┬────┬────┐        │
│ │... │100 │101 │...     │ ← 🧠 shared, reused
│ └────┴────┴────┘        │
└────────────────────────┘


Both a and b point to the same Integer object in the heap when the value is within the cached range.

πŸ”₯ What happens outside the range?


Integer x = 128;
Integer y = 128;
System.out.println(x == y); // ❌ false

Integer.valueOf(128) creates new objects, not from the cache.

πŸ’‘ Fun Fact:

You can change the cache range at JVM startup (not recommended):


-Djava.lang.Integer.IntegerCache.high=255

That would cache from -128 to 255.

🧡 Summary:

Feature Location
Integer a = 100; Stack (reference)
IntegerCache.cache[] Heap (actual cached objects)
Value outside cache Heap (new object each time)


πŸ§ƒ 7. The Dumb Questions That Actually Matter

Question ❓Answer ✅
Is == always reference compare?❌ No — depends on types
Are int and Integer treated same?❌ Nope, one is primitive, one is object
Why is 127 working, 128 not?Because of Integer cache (−128 to 127)
Why does Integer == int work?Java auto-unboxes the object to compare values
Are object references in stack?✅ Yes! But they point to heap objects
Is there heap involved in int a = 128?❌ No. Only stack — just raw value

πŸ“œ 8. Final Rules to Live By (with Emojis 😎)

  • πŸ”Ή int == int → ✅ compares values
  • πŸ”Ή Integer == Integer → ❌ compares references
  • πŸ”Ή Integer == int → ✅ unboxes & compares values
  • πŸ”Ή Use .equals() to compare objects safely
  • πŸ”Ή Don't rely on == unless you're 100% sure of what you're comparing
  • πŸ”Ή Java caches small Integers (−128 to 127) — don’t assume it for all values

πŸ§‘‍πŸ’» 9. Developer Tip πŸ’¬

"If you're not sure whether you're holding a value or a reference, you're probably comparing the wrong thing with ==."

 

🎁 Wrapping Up

This one line of code taught me more about Java memory, references, unboxing, and compiler behavior than most tutorials ever did.

The next time you write:

if (a == b)

Ask yourself:
🧠 Are you comparing values or just hoping they're pointing to the same object?

πŸ“’ Over to You!

  • πŸ‘¨‍πŸ’» Have you ever been shocked by a == behaving weirdly?
  • 😱 Ever wasted 2 hours debugging a bug that was just a reference comparison?


Comments

Popular posts from this blog

πŸ” Is final Really Final in Java? The Truth May Surprise You 😲

πŸ’¬ “When I was exploring what to do and what not to do in Java, one small keyword caught my eye — final . I thought it meant: locked, sealed, frozen — like my fridge when I forget to defrost it.”   But guess what? Java has its own meaning of final… and it’s not always what you expect! πŸ˜… Let’s break it down together — with code, questions, confusion, jokes, and everything in between. 🎯 The Confusing Case: You Said It's Final... Then It Changed?! 🫠 final List<String> names = new ArrayList <>(); names.add( "Anand" ); names.add( "Rahul" ); System.out.println(names); // [Anand, Rahul] 🀯 Hold on... that’s final , right?! So how on earth is it still changing ? Time to dive deeper... 🧠 Why Is It Designed Like This? Here’s the key secret: In Java, final applies to the reference , not the object it points to . Let’s decode this like a spy mission πŸ•΅️‍♂️: Imagine This: final List<String> names = new ArrayList <>(); Be...

🌟 My Journey – From Zero to Senior Java Tech Lead 🌟

 There’s one thing I truly believe… If I can become a Java developer, then anyone in the world can. πŸ’― Sounds crazy? Let me take you back. πŸ•“ Back in 2015… I had zero coding knowledge . Not just that — I had no interest in coding either. But life has its own plans. In 2016, I got a chance to move to Bangalore and joined a Java course at a training center. That’s where it all started — Every day, every session made me feel like: "Ohhh! Even I can be a developer!" That course didn’t just teach Java — it gave me confidence . πŸ§ͺ Two Life-Changing Incidents 1️⃣ The Interview That Wasn't Planned Halfway through my course, I had to urgently travel to Chennai to donate blood to a family member. After that emotional rollercoaster, I found myself reflecting on my skills and the future. The next day, as I was preparing for my move to Bangalore to complete the remaining four months of my course, I randomly thought — "Let me test my skills... let me just see...

🎒 Java Loops: Fun, Fear, and ForEach() Fails

πŸŒ€ Oops, I Looped It Again! — The Ultimate Java Loop Guide You Won't Forget “I remember this question from one of my early interviews — I was just 2 years into Java and the interviewer asked, ‘Which loop do you prefer and why?’” At first, I thought, “Duh! for-each is cleaner.” But then he grilled me with cases where it fails. 😡 That led me to explore all loop types, their powers, and their pitfalls. Let’s deep-dive into every major Java loop with examples &  real-world guidance so you'll never forget again. πŸ” Loop Type #1: Classic For Loop — “The Old Reliable” ✅ When to Use: You need an index You want to iterate in reverse You want full control over loop mechanics ✅ Good Example: List<String> names = List.of("A", "B", "C"); for (int i = 0; i < names.size(); i++) { System.out.println(i + ": " + names.get(i)); } πŸ”₯ Reverse + Removal Example: List<String> item...