我知道这个帖子已经很老了,但这是一个非常基本的问题,我认为它值得澄清。
问题是正确的。我认为这是 Java String.substring(int beginIndex, int endIndex) 方法中的软件故障。
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring%28int,%20int%29.
来自 Java 文档https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Java/C/C++ 和我所知道的所有其他语言都不会将数组索引视为数组元素之间的“分隔符”。
参数:
beginIndex - 起始索引,包括在内。
endIndex - 结束索引,不包含。
endIndex 名称错误,因为该语言不允许内存访问 endIndex + 1 处的地址,该地址需要包含最后一个数组元素,或者 endIndex 定义错误并且必须是:
endIndex - 结束索引,包括。
最有可能的情况是第二个参数命名错误。它应该是:
length - 从 beginIndex 开始的所需字符串的长度。
我们知道 Gosling 基于 C/C++ 语言的 Java 语法是为了熟悉。从C++字符串类http://www.cplusplus.com/reference/string/string/substr/我们看到方法定义是:
string substr (size_t pos = 0, size_t len = npos) const;
请注意,方法定义中的第二个参数是 'len' 表示长度。
长度
要包含在子字符串中的字符数(如果字符串较短,则使用尽可能多的字符)。
testString 有 10 个字符,索引位置为 0 到 9。指定 10 的 endIndex 应该总是抛出 IndexOutOfBoundsException(),因为 testString 没有 10 的 endIndex。
如果我们用 C++ 方法的具体值测试 JUnit 中的方法,我们期望:
字符串 testString = "testString";
assertThat(testString.substring(4, 6), equalTo("String"));
但我们当然会得到 Expected: "String" but was "St"
'String' 中从索引 0 到字符 'g' 的 testString 长度为 10 个字符。
如果我们使用 10 作为 'endIndex' 参数,
字符串 testString = "testString";
assertThat(testString.substring(4, 10), equalTo("String"));
来自 JUnit 的“通过”。
如果我们将参数 2 重命名为“lengthOfSubstringFromIndex0”,则您不必进行 endIndex - 1 计数,并且它永远不会抛出 IndexOutOfBoundsException(),而在指定 endIndex 10 时,它超出了底层数组。 http://docs.oracle.com/javase/7/docs/api/java/lang/IndexOutOfBoundsException.html
这只是您必须记住这种方法的特殊性的那些时候之一。第二个参数命名不正确。 Java 方法签名应该是:
public String substring(int beginIndex,
int lengthOfSubstringFromIndex0)
或重新定义方法以匹配 C++ string::substr 方法。重新定义当然意味着重写整个互联网,所以不太可能。