Why is this an issue?

There are various String operations that take one or more character indexes as arguments and return a portion of the original string. Indexing in this context is zero-based, meaning that the first character’s index is 0. As a result, given a string myString, its last character is at index myString.length() - 1.

The String operation methods throw a StringIndexOutOfBoundsException when one of their index argument is smaller than 0 (E.G.: -1). String::substring also throws this exception when the beginIndex or endIndex argument is larger than myString.length(), and String::charAt when the index argument is larger than myString.length() - 1 For instance, it is not possible to use String::charAt to retrieve a value before the start or after the end of a string. Furthermore, it is not possible to use String::substring with beginIndex > endIndex to reverse the order of characters in a string.

This rule raises an issue when a negative literal or an index that is too large is passed as an argument to the String::substring, String::charAt, and related methods. It also raises an issue when the start index passed to String::substring is larger than the end index.

How to fix it

Use non-negative indexes that are smaller than or equal to the length of the string in question with String::substring and strictly smaller with String::charAt.

Code examples

Noncompliant code example

String speech = "Lorem ipsum dolor sit amet";

String substr1 = speech.substring(-1, speech.length()); // Noncompliant, -1 is out of bounds
String substr2 = speech.substring(speech.length(), 0);  // Noncompliant, the beginIndex must be smaller than or equal to the endIndex
char ch = speech.charAt(speech.length());               // Noncompliant, speech.length() is out of bounds

Compliant solution

String speech = "Lorem ipsum dolor sit amet";

String substr1 = speech;                                         // Compliant, no string operation used
String substr2 = new StringBuilder(speech).reverse().toString(); // Compliant, the string can be reversed using StringBuilder::reverse()
char ch = speech.charAt(speech.length() - 1);                    // Compliant, speech.length() - 1 is in bounds.