What does String.substring exactly do in Java?
Categories:
Understanding Java's String.substring() Method

Explore the functionality, usage, and common pitfalls of the String.substring()
method in Java, including its behavior with indices and edge cases.
The String.substring()
method is a fundamental utility in Java for extracting a portion of a string. It allows developers to create new strings from existing ones by specifying start and end indices. While seemingly straightforward, understanding its precise behavior, especially concerning index boundaries, is crucial to avoid common errors like IndexOutOfBoundsException
.
How String.substring() Works
Java's String
class provides two overloaded versions of the substring()
method:
public String substring(int beginIndex)
public String substring(int beginIndex, int endIndex)
Both methods return a new string that is a substring of the original string. It's important to remember that strings in Java are immutable, so substring()
always creates a new String
object rather than modifying the original.
The substring(int beginIndex)
Method
This version extracts a substring starting from the specified beginIndex
and extending to the end of the original string. The character at beginIndex
is included in the new substring.
Index Rules:
beginIndex
must be greater than or equal to 0.beginIndex
must be less than or equal to the length of the string.
If beginIndex
is equal to the length of the string, an empty string is returned. If beginIndex
is less than 0 or greater than the string's length, an IndexOutOfBoundsException
is thrown.
String original = "Hello World";
String sub1 = original.substring(6); // "World"
String sub2 = original.substring(0); // "Hello World"
String sub3 = original.substring(original.length()); // "" (empty string)
System.out.println(sub1); // Output: World
System.out.println(sub2); // Output: Hello World
System.out.println(sub3); // Output: (empty line)
Examples of substring(int beginIndex)
The substring(int beginIndex, int endIndex)
Method
This more commonly used version extracts a substring starting from beginIndex
and extending up to, but not including, the character at endIndex
. This means the character at beginIndex
is included, but the character at endIndex
is not.
Index Rules:
beginIndex
must be greater than or equal to 0.endIndex
must be less than or equal to the length of the string.beginIndex
must be less than or equal toendIndex
.
If any of these conditions are violated, an IndexOutOfBoundsException
is thrown. If beginIndex
is equal to endIndex
, an empty string is returned.
String original = "Java Programming";
String sub1 = original.substring(0, 4); // "Java"
String sub2 = original.substring(5, 16); // "Programming"
String sub3 = original.substring(5, 5); // "" (empty string)
String sub4 = original.substring(0, original.length()); // "Java Programming"
System.out.println(sub1); // Output: Java
System.out.println(sub2); // Output: Programming
System.out.println(sub3); // Output: (empty line)
System.out.println(sub4); // Output: Java Programming
Examples of substring(int beginIndex, int endIndex)
flowchart LR A["Original String: 'Hello World'"] B["substring(0, 5)"] C["substring(6)"] D["substring(6, 11)"] A --> B A --> C A --> D B --> B_Result["Result: 'Hello'"] C --> C_Result["Result: 'World'"] D --> D_Result["Result: 'World'"] subgraph Index Visualization idx0["H (0)"] --> idx1["e (1)"] --> idx2["l (2)"] --> idx3["l (3)"] --> idx4["o (4)"] --> idx5[" (5)"] --> idx6["W (6)"] --> idx7["o (7)"] --> idx8["r (8)"] --> idx9["l (9)"] --> idx10["d (10)"] end B_Result -- "Indices 0 to 4" --> idx0 B_Result -- "" --> idx4 C_Result -- "Indices 6 to 10" --> idx6 C_Result -- "" --> idx10 D_Result -- "Indices 6 to 10" --> idx6 D_Result -- "" --> idx10
Visualizing substring()
behavior with indices
substring(beginIndex, endIndex)
is that endIndex
represents the first character not included in the substring. This makes calculating lengths easier: length = endIndex - beginIndex
.Common Pitfalls and Best Practices
While substring()
is powerful, incorrect usage can lead to runtime errors. Here are some points to consider:
IndexOutOfBoundsException
: This is the most common error. Always ensure yourbeginIndex
andendIndex
are within the valid range0
tostring.length()
. It's good practice to validate indices before callingsubstring()
.- Off-by-One Errors: Due to the exclusive nature of
endIndex
, it's easy to make off-by-one errors. Double-check yourendIndex
to ensure it correctly excludes the desired character. - Performance Considerations (Pre-Java 7 Update 6): In older Java versions,
substring()
could lead to memory leaks or inefficiencies because the new string shared the underlying character array of the original string. This meant a small substring could prevent a very large original string from being garbage collected. This behavior was changed in Java 7 Update 6 and later versions, wheresubstring()
now creates a completely new character array, thus avoiding this specific memory issue. For modern Java applications, this is generally not a concern, but it's good historical context.
String text = "Example";
// Correct usage
String subCorrect = text.substring(0, 3); // "Exa"
// Incorrect usage - will throw IndexOutOfBoundsException
try {
String subError1 = text.substring(-1); // beginIndex < 0
} catch (IndexOutOfBoundsException e) {
System.out.println("Error: " + e.getMessage());
}
try {
String subError2 = text.substring(text.length() + 1); // beginIndex > length
} catch (IndexOutOfBoundsException e) {
System.out.println("Error: " + e.getMessage());
}
try {
String subError3 = text.substring(0, text.length() + 1); // endIndex > length
} catch (IndexOutOfBoundsException e) {
System.out.println("Error: " + e.getMessage());
}
try {
String subError4 = text.substring(3, 2); // beginIndex > endIndex
} catch (IndexOutOfBoundsException e) {
System.out.println("Error: " + e.getMessage());
}
Demonstrating IndexOutOfBoundsException
scenarios
L
is at index L-1
.