Java Integer Cache Gotcha: Using .equals() for Correct Comparisons

The Integer Cache Trap : The Problem : Order matching works perfectly in all tests — order IDs 1 to 100 always compare correctly. In production with real order IDs above 127, identical orders never match. The logic is silently broken. No exception. No error. Just wrong results. Root Cause : Java caches Integer objects for values -128 to 127 at startup. Any Integer in this range is always the same object in memory. Outside this range, each Integer.valueOf() (including autoboxing) creates a new object. == compares object references, not values. So: java Integer a = 100; Integer b = 100; System.out.println(a == b); // true ✓ (same cached object in pool) Integer x = 200; Integer y = 200; System.out.println(x == y); // false ✗ (two different objects!) In production code java // ❌ BUGGY — works for id=5, silently wrong for id=500 public boolean isSameOrder(Integer id1, Integer id2) { return id1 == id2; // reference comparison! } isSameOrder(5, 5) → true ✓ (cached, same object) isSameOrder(200, 200) → false ✗ (different objects, same value) The cache boundary java Integer.valueOf(127) == Integer.valueOf(127) // true — cached Integer.valueOf(128) == Integer.valueOf(128) // false — not cached The cache range -128 to 127 is mandated by the JLS (Java Language Specification). The upper bound can be extended with -XX:AutoBoxCacheMax=<N> JVM flag — but relying on this is a terrible idea. ✅ Fix — Always use .equals() for boxed types java // ✓ CORRECT — value comparison, works for all ranges public boolean isSameOrder(Integer id1, Integer id2) { return Objects.equals(id1, id2); // null-safe, value-based } Three safe options java // Option 1: Objects.equals() — null-safe Objects.equals(id1, id2); // Option 2: .equals() with null guard id1 != null && id1.equals(id2); // Option 3: unbox to primitive (NPE risk if null) id1.intValue() == id2.intValue(); // or simply: (int) id1 == (int) id2; // auto-unbox — NullPointerException if null Prevention Checklist : -> Never use == to compare Integer, Long, Double, Float, Short, Byte, Character -> Always use Objects.equals(a, b) for nullable boxed comparisons -> Use primitive int, long instead of Integer, Long where null is not needed -> Write unit tests with values outside -128 to 127 (use 200, 500, 1000) -> Enable IntelliJ's "Suspicious equality check" inspection — it flags == on boxed types. IntelliJ Warning -> IntelliJ IDEA flags this automatically: ⚠ Integer equality check with == may not work for values outside -128..127 The Lesson : Java caches Integer objects only for -128 to 127. == on Integer compares references — not values.Tests with small IDs (1–100) will always pass. Production with real IDs (500+) will silently fail.Always use .equals() or Objects.equals() for any boxed type. No exceptions. #JavaInProduction #RealWorldJava #Java #SpringBoot #BackendDevelopment #ProductionIssues #DataStructures #DSA #SystemDesign #SoftwareEngineering #JavaDeveloper #Programming

  • graphical user interface, text

To view or add a comment, sign in

Explore content categories