5

This probably has a very obvious answer, but I just started learning Java and discovered this.

Say we have

String x = "apple";

Why is it that x.substring(5) returns "", an empty string while x.substring(6) throws an IndexOutOfBounds exception? Is there some kind of empty string that can be referenced appended to every string? Just not sure how it works.

Thanks!

Munawir
  • 3,346
  • 9
  • 33
  • 51
qwert
  • 331
  • 2
  • 12
  • [Similar question](http://stackoverflow.com/questions/3568222/array-slicing-in-ruby-looking-for-explanation-for-illogical-behaviour-taken-fr/3568281#3568281) for Ruby - the reasoning is identical. – Amadan Mar 25 '16 at 02:13
  • Because that's the way they designed it. – user207421 Mar 25 '16 at 02:59
  • This should help to understand idea of substring better: [Substring Method In String Class Reaches The Index It Isn't Supposed To](http://stackoverflow.com/questions/33600767/substring-method-in-string-class-reaches-the-index-it-isnt-supposed-to) – Pshemo Mar 25 '16 at 03:18
  • Thank you! I understand now. – qwert Mar 25 '16 at 23:15

3 Answers3

4

Javadoc says for public String substring(int beginIndex): "Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex."

The length of "apple" is 5, so the length of x.substring(5) is 5 - 5 == 0.

On the other hand the api doc says that if "... endIndex is larger than the length of this String object ..." the exception you experienced is thrown. For x.substring(6) your endIndex is 6 while the length of the String object is 5.

You are asking "Is there some kind of empty string that can be referenced appended to every string?". I would say yes, that's true in some way: the empty string is 'contained' at any position of any string, and it can be appended to any string without changing it. But I'm not sure if this way of viewing it helps...

yaccob
  • 1,230
  • 13
  • 16
  • Yeah that kind of makes sense. So for x.substring(5), endIndex == beginIndex, but endIndex cannot exceed the string length so x.substring(6) throws the exception. Got it. Thanks! – qwert Mar 25 '16 at 02:46
3

The Java substring accepts values 0 through variable.length (inclusive).

The number given refers not to the location of a character, but to the location of the point between to characters. For example:

0 :a: 1 :p: 2 :p: 3 :l: 4 :e: 5

5 returns an empty string because there are no characters after.

6 throws an Exception because there is no sixth location.

user2864740
  • 60,010
  • 15
  • 145
  • 220
Preston159
  • 300
  • 1
  • 3
  • 10
  • Wow nice and clear explanation thank you so much! Yeah, I thought it directly referred to the index of the character. That's interesting! The charAt() method does refer directly to indices though, right? – qwert Mar 25 '16 at 02:41
  • Yes, the charAt() method refers to the indices of the characters themselves. – Preston159 Mar 25 '16 at 02:43
-1

This is the source of substring

public String substring(int beginIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    int subLen = value.length - beginIndex;    // if less than 0, throw Exception   
                            //the value.length is your String.length 
    if (subLen < 0) {
        throw new StringIndexOutOfBoundsException(subLen);
    }
    return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}

and when your beginIndex is biger then the value.length(String.length) this will be an Exception

Timi
  • 892
  • 1
  • 8
  • 17