skip to content

Why is new Integer(5) deprecated, and what should you use instead?

level: middleimportance: should knowfreq 55%

answer

  1. Constructors deprecated since Java 9 (forRemoval)
  2. Constructor always allocates; valueOf caches -128..127
  3. Use valueOf or autoboxing instead
  4. new Integer encourages the == identity bug
  5. Applies to all wrapper types

basics

~10 s

new Integer(5) always creates a brand-new object and wastes memory. Use Integer.valueOf(5) (or just autoboxing, Integer x = 5;) instead, which can reuse cached objects.

solid answer

~40 s

The wrapper constructors like new Integer(5) were deprecated in Java 9 (and marked for removal later) because they always allocate a fresh object and bypass the value cache. Integer.valueOf(5) is the recommended factory: for small values (-128..127) it returns a shared cached instance, so it is more memory-efficient and lets the JVM optimize. The constructor also implies that distinct objects with the same value are meaningfully different, which encourages the == comparison bug. Autoboxing (Integer x = 5;) compiles to valueOf, so it is equally fine. The same applies to the other wrappers (Long, Double, Boolean...). Bottom line: never use the wrapper constructors; use valueOf or autoboxing, and compare wrapper values with equals, not ==.

code

java · 8 lines
java
// Avoid: always allocates, deprecated since Java 9
Integer bad = new Integer(5);

// Prefer: factory (cached for -128..127)
Integer good = Integer.valueOf(5);

// Equivalent: autoboxing compiles to Integer.valueOf(5)
Integer boxed = 5;

go deeper

for a junior

Knows you should use Integer.valueOf(5) or Integer x = 5; instead of new Integer(5).

for a middle

Explains the constructor always allocates while valueOf caches, and that the constructor is deprecated since Java 9.

for a senior

Ties the deprecation to allocation/GC pressure, the == identity pitfall, and the forRemoval intent across all wrappers.

for a principal

Discusses the migration/removal roadmap, library-wide implications, and how value-based class semantics (and Valhalla) make identity-bearing wrapper instances undesirable.

## What was deprecated Every boxed wrapper had public constructors, e.g. `new Integer(int)`, `new Integer(String)`, `new Double(double)`, `new Boolean(boolean)`. **Since Java 9** these constructors are `@Deprecated` (and annotated `forRemoval = true` in later versions). The intended replacements are the static factory methods `Integer.valueOf(...)`, `Double.valueOf(...)`, `Boolean.valueOf(...)`, etc. ## Reason 1 — always allocates, never caches A constructor, by definition, **must create a new object** every time it is called. So `new Integer(5)` always allocates a fresh heap object. The factory `Integer.valueOf(5)` is free to return a **cached, shared instance**: the spec mandates a cache for values **-128..127**, so repeated `valueOf` calls for small numbers reuse one object. In code that boxes many small numbers, the constructor produces a lot of needless garbage that the factory avoids. ## Reason 2 — encourages the == bug Having distinct objects with equal values invites comparing wrappers with `==`, which compares **references (identity)**, not values. With constructors `new Integer(5) == new Integer(5)` is always `false`. Funneling everyone through `valueOf` (and discouraging fresh allocation) reduces the surprise, though the right fix is to compare with `.equals()` or unbox to a primitive. ## The correct alternatives ```java Integer a = Integer.valueOf(5); // explicit factory — cached for small values Integer b = 5; // autoboxing — compiles to Integer.valueOf(5) ``` Both are preferred over `new Integer(5)`. Autoboxing is just syntactic sugar over `valueOf`, so it inherits the caching benefit. ## Generalizes to all wrappers The same deprecation and advice apply to `Long`, `Short`, `Byte`, `Character`, `Boolean`, `Float`, and `Double`: use `valueOf` or autoboxing, never the constructor. (`Boolean` is an extreme case — there are only two distinct values, `Boolean.TRUE` and `Boolean.FALSE`, so allocating new ones is pure waste.) ## Takeaway **Never call a wrapper constructor.** Prefer `valueOf` (or autoboxing). Compare wrapper values with `equals` or by unboxing, not `==`.

  • Does autoboxing use the constructor or valueOf?
    Autoboxing compiles to the valueOf factory, so it benefits from the small-value cache just like an explicit valueOf call.
  • Why is comparing wrappers with == risky?
    == compares references. Because of caching, equal small values may share an instance (== true) while large equal values do not (== false). Use equals() or unbox.

saying these in an interview costs you the question

  • Recommending new Integer(...) in new code
  • Saying the constructor and valueOf are interchangeable — only valueOf caches
  • Claiming the deprecation is purely stylistic — it is about allocation, caching, and a removal path
  • Suggesting == is a safe way to compare two wrapper objects

context