Java - 为什么str.substring(str.length())是可接受的代码行?

时间:2015-11-05 14:45:30

标签: java string substring

总而言之,为什么Java不会为这行代码抛出IndexOutOfBoundsException?

str.substring(str.length())

是否只是定义了IndexOutOfBoundsException?要使开始/结束索引采用相同的值范围以便编程方便/对称?这只是Oracle的决定吗?是否只有一个特殊情况下处理这种情况的包容性起始指数?或者有一些潜在的原因......

我阅读了文档,他们说它只返回空字符串("")。但我想知道这是否值得担心。它会改变吗?我没有想到,但我想从其他人那里听到。我有一些代码依赖于这样的行来工作,因为我使用substring和indexOf(...)+ 1来分割一些行,我真的不想在代码行周围放置不必要的逻辑

5 个答案:

答案 0 :(得分:10)

这是substring(beginindex) javadoc的文档。

  

返回一个新字符串,该字符串是此字符串的子字符串。子字符串以指定索引处的字符开头,并延伸到此字符串的末尾。

     

示例:

     

“unhappy”.substring(2)返回“happy”

     

“Harbison”.substring(3)返回“bison”

     

“空虚”.substring(9)返回“”(空字符串)

     

参数:   beginIndex起始索引,包括在内。

     

返回:   指定的子字符串。

     

抛出:   IndexOutOfBoundsException - 如果beginIndex为负或大于此String对象的长度。

基本上是因为它仅在beginindex > length时抛出,如果String则会返回空beginindex == length

正如@Kayaman指出的那样,Oracle不会为了改变这种情况而破坏对其他java版本的向后兼容性。

答案 1 :(得分:4)

如java docs中所述,仅当beginIndex 大于此String对象的长度时,才会抛出IndexOutOfBoundsException。

并且还从java docs

中查看以下示例
"emptiness".substring(9) returns "" (an empty string)

正如评论中所述,但charAt方法不一样。根据文档和API用户的观点,此方法是正确和精确的。

public char charAt(int index) {
    if ((index < 0) || (index >= count)) {     //          >= operator is used
        throw new StringIndexOutOfBoundsException(index);
    }
    return value[index + offset];
}

答案 2 :(得分:4)

你说你已经阅读了文档,所以你知道它会返回空字符串,因为那是文档所说的内容。但其根本原因如下:

出于substring的目的,字符串的索引被解释为在字符串中的字符之间。因此索引0在第一个字符之前,索引1在第一个和第二个字符之间,索引str.length()在最后一个字符之后。从最后一个字符开始的子字符串是&#34;&#34;。

在substring的双参数版本中更有意义,以这种方式定义它可以避免在提取可能包含或不包含最后一个字符的子字符串时编写特殊情况逻辑。

答案 3 :(得分:3)

另一种看待它的方式是

str.substring(0, x) + str.substring(x)

始终等同于s,其中0 <= x <= str.length()

为了解决x == str.length()不一致和烦人的单一案例 - 例如,您必须在解析循环中编写特殊情况。

另请参阅documentation for StringIndexOutOfBoundsException

  

通过String方法抛出,以指示索引是负数还是大于字符串的大小。对于某些方法(如charAt方法),当索引等于字符串的大小时,也会抛出此异常。

请注意第二句 - charAt 在索引等于字符串长度时抛出异常,因为该位置没有char回来。但从技术上讲,在该位置是一个有效的String - 它是一个零长度String,即""

这与其他&#34;切片&#34;一致。 java中的操作 - 例如,

list.subList(list.size(), list.size())

将返回一个空列表,而不是抛出异常。

答案 4 :(得分:1)

你的建议不符合逻辑。这些代码行

System.out.println("1 " + "***".substring(0));
System.out.println("2 " + "***".substring(1));
System.out.println("3 " + "***".substring(2));
System.out.println("4 " + "***".substring(3));

产生

1 ***
2 **
3 *
4

第四行输出遵循另一行的模式。抛出异常没有任何意义。