【发布时间】:2013-11-11 06:37:16
【问题描述】:
考虑以下场景:
String str = "str";
System.out.println("str subs: " + str.substring(3,3));
预期结果:StringIndexOutOfBoundsException(因为 beginIndex 在字符串结束“之后”开始)
实际结果:
打印空字符串
来自String.java:
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);
}
很容易看出,实现没有处理以下边缘情况:beginIndex == endIndex == count(count 是字符串的长度)。
根据the manual方法子串:
返回一个新字符串,它是该字符串的子字符串。子串 从指定的 beginIndex 开始并延伸到字符 index endIndex - 1。因此子字符串的长度是 endIndex-beginIndex.
它还指出该方法抛出:
IndexOutOfBoundsException - 如果 beginIndex 为负数,或者 endIndex 大于此 String 对象的长度,或 beginIndex 为 大于 endIndex。
makes sense 是否考虑以下情况:beginIndex == endIndex == count 有效?
我错过了什么吗?
【问题讨论】:
-
这当然是有争议的,但我个人喜欢这种行为。 PHP 的
substr函数在这种情况下返回false,我发现这是一个烦人的边缘情况,我从某个字符串缓冲区中提取数据,一旦它被完全清空而不是"",就会变成false,因此打破了后来的$buf === ""支票。 -
@Boann 我没有探索
substr,在 Java 中这种行为对我来说似乎 arguable (实际上 - 我正在寻找一个论点可以解释这种行为但没有找到——这就是我发布这个问题的原因。 -
子字符串
extends to the character at index endIndex - 1。你为什么不期待substring(0,0)例外? -
@Arian 因为
string[0]没有越界。 -
对于
endIndex = 0,要包含的最后一个字符位于-1,与startIndex = length一样超出范围。然而,您接受0,0成功。3,3也一样,只是从字符串的另一端开始。