Skip to content

NoValueOfOnStringType: keep String.valueOf when the argument can be null - #1022

Open
Niloyyy wants to merge 1 commit into
openrewrite:mainfrom
Niloyyy:novalueof-nullable-string
Open

NoValueOfOnStringType: keep String.valueOf when the argument can be null#1022
Niloyyy wants to merge 1 commit into
openrewrite:mainfrom
Niloyyy:novalueof-nullable-string

Conversation

@Niloyyy

@Niloyyy Niloyyy commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

The problem

String.valueOf(s) equals s only when s is not null — for a null String it produces "null". The recipe removed the call for any String-typed argument that wasn't a method invocation, so a nullable variable lost its conversion:

private static final String INCIDENT_OPEN_TASK = null;

templateBody.replace("$INCIDENT_OPEN_TASK", String.valueOf(INCIDENT_OPEN_TASK));
// became
templateBody.replace("$INCIDENT_OPEN_TASK", INCIDENT_OPEN_TASK);

Running both:

with valueOf : x=null
without      : THREW java.lang.NullPointerException

Method invocations were already excluded, and the reason is the same one that applies here — the value may be null. Identifiers, field accesses and casts are no safer. This also lines up the behavior with the recipe's own description, which says the simplification applies "when the argument to String#valueOf(arg) is a string literal".

The change

For String arguments, require the expression to be demonstrably non-null — a non-null literal, or a string concatenation.

The one thing I wanted to avoid was over-correcting. Inside a concatenation the removal is safe even for nulls, because + already renders a null operand as "null":

"p" + String.valueOf(f)   ->  pnull
"p" + f                   ->  pnull

My first attempt blocked that too, which would have lost a legitimate simplification. So removeValueOfForStringConcatenation now accepts String arguments alongside primitives, and that case keeps working.

Tests

Full suite locally on JDK 21: 2277 tests, 0 failures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Recipe NoValueOfOnStringType incorrectly removes String.valueOf on null-initialized constants, introducing runtime NPE

1 participant