← Debugging Guides

阅读中文版本

Java StringIndexOutOfBoundsException

Fix Java StringIndexOutOfBoundsException from substring and charAt calls with off-by-one indices or unchecked user input lengths.

beginnerdebuggingjavastrings

Symptoms

  • java.lang.StringIndexOutOfBoundsException: begin 0, end 5, length 3
  • substring(0, n) fails on short strings
  • charAt(i) throws when the string is empty

Possible causes

  • end index exceeds length or begin > end
  • charAt(0) on an empty string
  • The input was assumed to be a fixed length
  • A trimmed or split string is shorter than expected

Diagnosis steps

Read the lengths in the exception message

Interpretation

The message includes begin, end, and length, so you can see exactly which bound was violated.

Validate length before slicing

Interpretation

Guard with if (s.length() >= n) or use Math.min to clamp indices.

Trace the string source

Interpretation

If the value comes from user input, encoding, or a split, empties and short values are expected.

Root cause

String substring and charAt enforce bounds: an end index beyond the string length, begin > end, or an index on an empty string throws StringIndexOutOfBoundsException. It is an unchecked exception, so only validation or clamped indices prevent it.

Fix

Validate length before extracting, clamp end with Math.min(end, s.length()), and check for empty strings before charAt. Prefer modern helpers such as s.startsWith/endsWith and regex extraction. For fixed-width parsing, reject inputs that are too short with a domain-specific exception instead of letting the index error escape.

Verify the fix

Re-run with the previously failing and a shorter input in a test; both are handled without throwing, and the short case produces the intended fallback or clear error.

Symptoms

A substring or charAt call throws StringIndexOutOfBoundsException: begin 0, end 5, length 3. It appears on short or empty input while longer values work.

Diagnosis

Read the bounds from the message and check length first:

String s = readInput();
System.out.println(s.length());
String head = s.substring(0, Math.min(5, s.length()));

If the source is user input or a split result, empty values are expected.

Fix

Validate or clamp before extracting:

if (s.isBlank()) {
    throw new IllegalArgumentException("empty input");
}
int end = Math.min(5, s.length());
String head = s.substring(0, end);

char first = s.isEmpty() ? '\0' : s.charAt(0);

Verification

Test with both the failing input and a shorter string; neither throws, and the short case yields the documented fallback or clear domain error.

Reading the Bounds Message

The exception text is more helpful than it looks: begin 0, end 5, length 3 tells you the requested range and the real size in one line. When begin is greater than end the bug is reversed indices; when end exceeds length the caller assumed more characters than exist. Encoding-aware code must be careful too, because a multi-byte character occupies one index but several bytes, so slicing by byte offset after decoding, or decoding after slicing, produces mismatches that look like ordinary off-by-one errors.