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

Rya*_*rad 5 java string substring

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

str.substring(str.length())
Run Code Online (Sandbox Code Playgroud)

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

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

Som*_*Guy 10

这是substring(beginindex)javadoc 的文档.

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

例子:

"unhappy".substring(2)返回"happy"

"Harbison".substring(3)返回"野牛"

"emptiness".substring(9)返回""(空字符串)

参数:beginIndex起始索引,包括.

返回:指定的子字符串.

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

基本上因为它只是抛出if beginindex > length并将返回一个空的Stringif beginindex == length.

正如@Kayaman指出的那样,Oracle不会破坏与其他java版本的向后兼容性,只是为了改变它.


raj*_*uGT 5

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

并从java文档中查看以下示例

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

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

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


gat*_*kin 5

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

出于子字符串的目的,字符串的索引被解释为在字符串中的字符之间。所以索引 0 在第一个字符之前,索引 1 在第一个和第二个之间,索引 str.length() 在最后一个字符之后。在最后一个字符之后开始的子串是“”。

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