子串奇怪的界限?

Substring strange Bounds?

所以,我想弄清楚为什么 String.substring(int startIndex) 允许起始索引越界并且不会抛出 OOB 异常?

这是我用来测试的代码:

public class testSub {
public static void main(String[] args) {
    String testString = "D";
    String newSub= testString.substring(1); //print everything FROM this index Up, right? Should that not be out of bounds? Yet I just get a blank.
    System.out.println(newSub); //this works fine and prints a blank
    System.out.println(testString.charAt(1));  // <Yet this throws OOB?
    System.out.println(testString.lastIndexOf("")); // Gives me (1) but I just tried getting it? Should this not mean String length is 2?
    }
}

我明白子串是子串(包括,不包括),但是1显然是越界的,所以为什么它给出一个空白space而不是抛出OOB,或者它是怎么做到的? “”是一些特殊的例外吗?

如文档所述:

 * IndexOutOfBoundsException  if
 *             <code>beginIndex</code> is negative or larger than the
 *             length of this <code>String</code> object.

仅当 beginIndex 大于 length 时才会抛出 IndexOutOfBoundsException。在您的情况下,两个值都相等。

查看 String.substring(int beginIndex) 的 Javadoc 以了解它何时抛出 IndexOutOfBoundsException:

IndexOutOfBoundsException - if the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex.

由于字符串长度为 1 而您使用 1 调用它,因此您没有得到 IndexOutOfBoundsException

由于您的字符串长度为 1 并且字符串由 char 数组支持,因此您只需 char[0] 填充 D 作为值(注意数组索引从 0 而不是 1 开始)。现在您正在尝试使用 charAt 方法从字符串(间接字符数组)访问第一个索引,例如:

System.out.println(testString.charAt(1));

因此你得到 IOOB 异常。

如果你想访问字符串中的第一个字符,你应该使用:

System.out.println(testString.charAt(0));

根据 JavaDoc,仅当索引 > 字符串对象的长度时,子字符串方法才会抛出异常。 仅当索引不小于对象的长度时,图表方法才会抛出异常。

子字符串方法(int beginIndex)

参数: beginIndex 开始索引,包括在内。 Returns: 指定的子字符串。 投掷: IndexOutOfBoundsException - 如果 beginIndex 为负数或大于此字符串的长度

ChartAT 方法

Returns 指定索引处的字符值。索引 范围从 0 到 length() - 1。 序列在索引 0 处,下一个在索引 1 处,依此类推, 至于数组索引。 如果索引指定的 char 值是代理项, 代理值被返回。 指定者:CharSequence 中的 charAt(...) 参数: 索引 char 值的索引。 Returns: 此字符串的指定索引处的 char 值。 第一个 char 值位于索引 0 处。 投掷: IndexOutOfBoundsException - 如果索引 参数为负或不小于此长度 细绳。 对象。

马西奥说的。加:方法lastIndexOf不是你想的那样。它是 this 中参数子串的最后一个索引。对于空字符串参数,它总是长度加一!

好吧,人们一直在抛出 java 文档,但这并不能真正回答问题。

您可以执行 "D".substring(1) 的原因是您要求从索引 1 开始到索引 1(不包括)的字符串。根据定义,这是空字符串,因为它的大小为 1-1=0。每个字符串的开头、结尾和每个字符之间都有一个空字符串。例如。 "" + "B" + "O" + "" + "B" + "" = "BOB".