为什么'substring(startIndex,endIndex)'不会抛出"超出范围"

mas*_*san 18 java substring

在Java中我使用的substring()方法,我不知道为什么它不会抛出"out of index"错误.

该字符串的abcde索引从0开始到4,但该substring()方法将startIndex和endIndex作为参数,基于我可以调用foo.substring(0)并获取"abcde"的事实.

那么为什么子串(5)有效呢?该指数应该超出范围.解释是什么?

/*
1234
abcde
*/
String foo = "abcde";
System.out.println(foo.substring(0));
System.out.println(foo.substring(1));
System.out.println(foo.substring(2));
System.out.println(foo.substring(3));
System.out.println(foo.substring(4));
System.out.println(foo.substring(5));
Run Code Online (Sandbox Code Playgroud)

此代码输出:

abcde
bcde
cde
de
e
     //foo.substring(5) output nothing here, isn't this out of range?
Run Code Online (Sandbox Code Playgroud)

当我用6替换5时:

foo.substring(6)
Run Code Online (Sandbox Code Playgroud)

然后我得到错误:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
    String index out of range: -1
Run Code Online (Sandbox Code Playgroud)

Mat*_*ell 21

根据Java API doc,当起始索引大于String 的Length时,substring会引发错误.

IndexOutOfBoundsException - 如果beginIndex为负或大于此String对象的长度.

事实上,他们举了一个像你的例子:

"emptiness".substring(9) returns "" (an empty string)
Run Code Online (Sandbox Code Playgroud)

我想这意味着最好将Java String视为以下内容,其中索引包含在|:

|0| A |1| B |2| C |3| D |4| E |5|
Run Code Online (Sandbox Code Playgroud)

也就是说字符串同时具有开始和结束索引.

  • 希望javadoc可以对此有一个注释,或者像我这样的粗心大意的人如果beginIndex = String.length()会发生`IndexOutOfBoundsException`. (4认同)

Jef*_*eff 16

当你这样做时foo.substring(5),它获得从"e"之后的位置开始并在字符串结尾处结束的子字符串.顺便提一下,开始和结束位置恰好相同.因此,空字符串.您可以将索引视为字符串中的实际字符,而不是字符之间的位置.

        ---------------------
String: | a | b | c | d | e |
        ---------------------
Index:  0   1   2   3   4   5
Run Code Online (Sandbox Code Playgroud)