Case Conversion Chained With equals()

ID

java.locale_case_then_equals

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

best-practice, reliability

Description

Reports chained calls like s.toUpperCase().equals("FOO") or s.toLowerCase().equals("bar"), as well as the reversed form "FOO".equals(s.toUpperCase()). These patterns should use equalsIgnoreCase() instead, which is both more efficient and locale-safe.

Rationale

toUpperCase() and toLowerCase() are locale-sensitive. In the Turkish locale, for example, 'i'.toUpperCase() produces a dotted capital I ('\u0130'), not 'I'. This means s.toUpperCase().equals("FOO") can give different results depending on the JVM’s default locale, leading to subtle, hard-to-reproduce bugs.

Additionally, toUpperCase() creates a new String object that is used only for the comparison and then discarded, wasting memory.

// Bad -- locale-dependent and creates intermediate String
if (s.toUpperCase().equals("FOO")) { ... }
if ("foo".equals(s.toLowerCase())) { ... }

Remediation

Use equalsIgnoreCase() which handles case-insensitive comparison correctly across all locales.

// Good -- locale-safe and no intermediate String
if (s.equalsIgnoreCase("FOO")) { ... }