-3

考虑以下场景:

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 == countcount字符串的长度)。

根据手册,方法子字符串:

返回一个新字符串,它是该字符串的子字符串。子字符串从指定的 beginIndex 开始并延伸到索引 endIndex - 1 处的字符。因此子字符串的长度是 endIndex-beginIndex。

它还指出该方法抛出:

IndexOutOfBoundsException - 如果 beginIndex 为负数,或者 endIndex 大于此 String 对象的长度,或者 beginIndex 大于 endIndex。

考虑 case: as valid 是否有意义?我错过了什么吗?beginIndex == endIndex == count

4

3 回答 3

7
"abc".substring(3,3) == ""

As you said, let's look at the manual:

Returns a new string that is a substring of this string.

okay

The substring begins at the specified beginIndex and extends to the character at index endIndex - 1.

The interpretation of this sentence is difficult regardless of the length of the string. But I think we can agree that an empty string does not violate this.

Thus the length of the substring is endIndex-beginIndex.

okay

Throws: IndexOutOfBoundsException - if the beginIndex is negative

it is not

or endIndex is larger than the length of this String object

it is not

or beginIndex is larger than endIndex.

it is not.

Behavior seems as promised to me.

You can also see it like this: the string "abc" contains four empty substrings, two between the characters, one at the beginning, and one at the end. They can be accessed via substring with 1,1 and 2,2, 0,0, and 3,3, respectively. Compare also with the following code

class EmptyTest {

    public static void main (String[] args) {

         Matcher m = Pattern.compile("").matcher("abc");
         while (m.find()) {
            System.out.println(m.start() + "," + m.end());
         }
    }
}

which prints

0,0
1,1
2,2
3,3
于 2013-11-11T09:07:35.850 回答
2

beginIndex == endIndex == count意味着虚拟“开始光标”将放置在字符串中的最后一个字符之后,与“结束光标”在同一点,所以你会得到一个零长度的字符串。它似乎与返回空字符串一样有效(0,0)

于 2013-11-11T06:39:22.477 回答
0

这种行为符合:

String str = "str";
System.out.println("str subs: " + str.substring(2,2));

还返回空字符串而不是子字符串。空集是所有集的子集。

参考类 java.lang.String 参数:beginIndex 开始索引,包括。

于 2013-11-11T06:48:29.820 回答