An off-by-one error is a boundary mistake in which an index or iteration starts or stops one position too early or too late. An index equal to an array, list, or string length is invalid, because valid positions stop below that length. section 5.2
Common Java forms include:
- Accessing an element before checking that the string is nonempty or that the index is valid. section 5.2
- Using a reversed relation, such as checking data.length < index when the intended condition concerns index < data.length. section 5.2
- Rejecting index values greater than length while accidentally accepting index == length. section 5.2
- Reversing a loop but keeping i++ instead of i--, or using hi instead of hi - 1 as the initial index. section 3.6
A backward loop with the correct boundary
A forward loop over [lo, hi) includes lo and excludes hi. Its descending equivalent is `for (int i = hi - 1; i >= lo; i--)`. Starting at hi accesses one position beyond the range; incrementing i can make the loop run zero times or continue until integer overflow. section 3.6
void processString(String s) {
if (Character.isDigit(s.charAt(0))) {
processStringStartingWithDigit(s);
}
}
Inspect the minimal empty-string failure: charAt(0) executes before any check that a character exists. section 5.2
for (int i = hi - 1; i >= lo; i--)
Compare the canonical descending loop against incorrect initial values, bounds, or update directions. section 3.6
Check bounds before indexing, and make the valid interval explicit. For a contiguous range, require nonnegative length, offset, and count, with count <= length - offset; this avoids overflow in offset + count. Java also provides Objects.checkIndex, checkFromToIndex, and checkFromIndexSize for standard validation. section 5.2
Static analysis can catch many access-before-check and wrong-direction-loop cases. IntelliJ IDEA and SonarLint detect update-direction mismatches, while PVS-Studio can flag the index-equals-length case. Complex index expressions may require intermediate variables, and intentional bounds choices still need review. section 5.2 section 3.6



