Avoid String Instantiation

ID

java.avoid_string_instantiation

Severity

info

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Efficiency

Language

Java

Tags

code-style

Description

Reports redundant new String(…​) constructor calls:

  • new String() — a zero-length string can be written as the literal "".

  • new String("literal") — wraps a constant that is already a String.

  • new String(existingString)String is immutable, copying it produces nothing useful.

Constructors that decode bytes (new String(bytes, charset)) or build from char[] are legitimate and are not flagged.

Rationale

String is immutable. Every distinct literal the compiler sees is already interned once, so wrapping a literal with new String("…​") allocates a second object whose only purpose is to defeat deduplication. Copy-constructing from an existing String (new String(s)) has the same effect without the literal-interning argument — the result is a pointer-distinct but value-equal object.

// Bad — allocates a pointless second String
String a = new String();           // same as ""
String b = new String("hello");    // same as "hello"
String c = new String(s);          // same as s

A common (bad) folk rule says "use new String(s) to trim a substring’s backing char array". Modern JDKs (JDK 7u6+) already avoid the shared-array pitfall, so this is no longer a reason to copy.

Remediation

Use the literal directly, or just reuse the existing reference:

// Good
String a = "";
String b = "hello";
String c = s;

When you do need to materialize a String from bytes or characters, the multi-arg constructors or new String(bytes, charset) remain correct and are not flagged.