1

substring returns a string starting with the specified index number all the way to the end. Can you tell me why the following is not a run time error?

String s = "Hello"; s.substring(5);

The length of the string is 5 but the last index is 4 so why do I not get an exception for range? I get one when I say s.substring(6);

Please help!

PTheCoolGuy
  • 63
  • 1
  • 7
  • possible duplicate of [Java: substring index range](http://stackoverflow.com/questions/4570037/java-substring-index-range) – Joe Dec 07 '14 at 05:22
  • Because it's important to have a way to return an empty string using this mechanism. If this weren't allowed it would make certain programs more difficult to write. This is just a design decision that the Java designers made, and I think it's the correct one, although you can make a case that `substring(6)` should also return an empty string. – ajb Dec 07 '14 at 05:35

4 Answers4

1

s.substring() doesn't actually throw a method if you call an index 1 above the last index. This is very helpful, because then you don't need to worry with forloops like this:

for(int i = 0; i < string.length - 1; i++) {
    System.out.println(s.substring(i, i+1));
}

No need to have a special check for the very last index, it'll just work.

You can see the Java Docs for the more technical answer - s.substring() will only throw an error if the index is greater than the LENGTH of the string, not just the number of indices.

See this question for more info too.

Community
  • 1
  • 1
Alex K
  • 8,269
  • 9
  • 39
  • 57
1

From the documentation:

Throws: IndexOutOfBoundsException - if beginIndex is negative or larger than the length of this String object.

5 is equal to the length of "Hello", so it's permitted.

August
  • 12,410
  • 3
  • 35
  • 51
1

The reason why it does not throw an exception is because in the two parameter version:

substring(int beginIndex, int endIndex)

endIndex is exclusive. When the single parameter version you're using specifies the length of the string, the behavior is consistent with the two parameter version, so its treated as exclusive. The result is an empty string.

The actual implementation of the single parameter version is:

public String substring(int beginIndex) {
        return substring(beginIndex, count);
}

For reference, the actual implementation of the two parameter version is:

public String substring(int beginIndex, int endIndex) {
  if (beginIndex < 0) {
    throw new StringIndexOutOfBoundsException(beginIndex);
  }
  if (endIndex > count) {
    throw new StringIndexOutOfBoundsException(endIndex);
  }
  if (beginIndex > endIndex) {
    throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
  }
  return ((beginIndex == 0) && (endIndex == count)) 
    ? this 
    : new String(offset + beginIndex, endIndex - beginIndex, value);
}
cfeduke
  • 23,100
  • 10
  • 61
  • 65
1

This is expected behaviour, API gives a similar example:

"emptiness".substring(9) returns "" (an empty string)
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275