Avoid Assignment In Loop Condition
ID |
java.loop_assignment_in_while_condition |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
efficiency |
Description
Reports while and do-while loops whose continuation condition contains an assignment expression.
if conditions are not covered here; they belong to java.assign_in_condition. The two rules are complementary: one condition produces at most one finding, from whichever rule owns it.
Configuration
| Property | Default | Meaning |
|---|---|---|
|
|
Do not report the canonical sentinel read loop, where the assignment is one side of a comparison whose other side is a literal — |
Assignments that are not sentinel comparisons are always reported, whatever the property says: while (b = next()), while m = pattern.matcher(s.find()), while ((i = i + 1) < n), and any assignment in a compound condition that is not itself compared against a literal.
Rationale
A condition like while (more = hasNext()) folds two things into a single expression: a side-effect (the assignment) and the control-flow test. That makes the loop harder to scan visually and easy to misread as the equality check ==. It also spreads the state-update across the condition and the body, so reasoning about the value of the variable on each iteration requires tracing the side-effect first.
// Bad — assignment used directly as the loop test, easily misread as ==
boolean more;
while (more = hasNext()) {
process();
}
// Bad — assigned, then immediately dereferenced
Matcher m;
while ((m = pattern.matcher(s)).find()) {
process(m.group());
}
// Good — assignment explicit, condition expresses the test
int line = read();
while (line > 0) {
process(line);
line = read();
}
// Allowed by default (allowReadLoop) — the sentinel read loop
String line;
while ((line = reader.readLine()) != null) {
process(line);
}
Remediation
Move the assignment out of the condition. Either initialize the loop variable before the loop and re-assign it at the end of the body, or convert the loop into a for with an explicit update section.