Java 字符串索引越界异常

是的,我知道如何解决这个问题。我正在研究字符串类和字符串生成器类之间的API。以下是我的问题:


StringBuilder sb = new StringBuilder("wibble");

String s = new String("wobble");


sb.charAt(index) //Can throw Index Out Of Bounds Exception

s.charAt(index) //Can throw Index Out of Bounds Exception


sb.substring(start, end) //Can throw STRING index out of bounds exception

s.substring(start, end) //Only throws Index out of Bounds Exception (no String)

因此,当它决定抛出StringIndexOutOfBoundsException与IndexOutOfBoundsException时,没有意义。是的,我知道StringIndex是一个子例外。在 String 和 StringBuilder 中,某些具有相同实现的方法会引发相同的异常,而在某些具有相同实现的方法中,StringBuilder 会引发 sub 异常。这是为什么呢?


为了节省人们滚动浏览答案的时间,并感谢2个人回答,即使我只能选择一个作为答案,两者都有助于澄清:Java Oracle Doc People在String的子字符串中打错了。它应该是StringIndexOutOfBoundsException。与 StringBuilder 中的 CharAt() 相同


扬帆大鱼
浏览 98回答 2
2回答

幕布斯6054654

这取决于您使用的 JDK 实现。我做了一些挖掘,找到了该类的实现方法(注意:我使用的是Oracle JDK 1.8)。public char charAt(int index)StringBuilder因此,在本例中,该类是 的子类。这是实现程序员的选择,因为你不会在文档中找到它。StringBuilderAbstractStringBuilder我发现该函数是在基类上实现的。以下是来自我的系统的相关代码的一些屏幕截图。(请记住,特定的JDK是Oracle和Java 1.8)。charAtAbstractStringBuilder更新我实际上运行了一些代码来测试抛出的异常,并发现了一些有趣的东西。我的环境中的函数还抛出了一个 .以下是我运行以测试它的代码:charAt()java.lang.StringIndexOutOfBoundsExceptionpublic class StringVsStringBuilder {    public static void main(String[] args) {        StringBuilder builder = new StringBuilder("one");        String string = "two";        try {            builder.charAt(10); // Clearly out of bounds        } catch (IndexOutOfBoundsException e) {            System.out.println(String.format(                    "Exception encountered accessing character out of index bounds on variable 'builder': %s",                    e.getClass()            ));        }        try {            string.charAt(10); // Clearly out of bounds        } catch (IndexOutOfBoundsException e) {            System.out.println(String.format(                    "Exception encountered accessing character out of index bounds on variable 'string': %s",                    e.getClass()            ));        }    }}以下是运行时的输出(Windows 10,64bit,Oracle JDK 1.8.0_191):Exception encountered accessing character out of index bounds on variable 'builder': class java.lang.StringIndexOutOfBoundsExceptionException encountered accessing character out of index bounds on variable 'string': class java.lang.StringIndexOutOfBoundsExceptionProcess finished with exit code 0要解决评论中的一些问题:[AbstractStringBuilder]不在文档中,这意味着我们不能用它编写程序?一个通常跟随另一个。该类是包的私有类,这意味着无法从该包的外部访问它。这意味着您将无法在代码中导入和使用此类。这是一个完美的例子,说明某些不属于系统公共API的代码部分(在本例中是JDK本身),在这种情况下,由于以下几个原因,它不会被记录:AbstractStringBuilderjava.lang您不能使用它实施细节可能会不断变化它不应影响公共API(系统的记录部分)的使用如果在抛出一个,那么为什么文档说简单?charAt()StringBuilderStringIndexOutOfBoundsExceptionIndexOutOfBoundsException这是因为这是基于类的设计意图所描述的函数行为。由于您可以为异常创建任意数量的子类(就像任何其他不是的Java类一样),因此始终由实现程序员选择最好从函数返回(或抛出)的内容,只要函数遵守商定的契约(接口,文档规范,抽象类, 等)。charAt()final话虽如此,您现在可以实现JDK,并选择自己的子类来投放此场景。如果我在我的代码中使用,我会捕获文档中描述的异常,因为这将允许我获得最大的灵活性/可移植性,而不会因依赖实现细节而中断风险。关于这个主题已经写了整本书,所以我将把讨论留在这里:总是尝试捕捉你知道可能被抛出的最具体的异常,这意味着,如果其他实现可能不会抛出,那么你最好抓住,因为它保证是该类型(或它的子类)。IndexOutOfBoundsExceptionStringBuilder.charAt()StringOutOfBoundsExceptionIndexOutOfBoundsException更新 2在这种特定情况下,您几乎可以忽略我上面提到的所有内容,而只关注以下内容:charAt()是 java.lang.CharSequence 中描述的一种接口方法。这意味着对于任何实现类,当尝试访问超出序列边界的索引时,引发的问题将是 .该接口描述了一般行为,并且没有必要用 、 a 、 an 或任何其他特定实现来定义此行为。如果这些暗示。决定对该异常进行子类化,并在每种情况下提供更具体的错误信息,这很好,但它不会更改总协定。如果您正在编写通用字符处理系统,那么您可能会写入接口而不关心底层 impl。在这种情况下,你只会知道(或关心)什么都没有。IndexOutOfBoundsExceptionStringStringBuilderAlphabetSoupIndexOutOfBoundsException

绝地无双

这似乎是一个文档拼写错误。在 Java HotSpot(TM) 10.0.1 中,确实抛出了 :String.substringStringIndexOutOfBoundsExceptionpublic String substring(int beginIndex, int endIndex) {&nbsp; &nbsp; int length = length();&nbsp; &nbsp; checkBoundsBeginEnd(beginIndex, endIndex, length); //here&nbsp; &nbsp; int subLen = endIndex - beginIndex;&nbsp; &nbsp; if (beginIndex == 0 && endIndex == length) {&nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; }&nbsp; &nbsp; return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : StringUTF16.newString(value, beginIndex, subLen);}static void checkBoundsBeginEnd(int begin, int end, int length) {&nbsp; &nbsp; if (begin < 0 || begin > end || end > length) {&nbsp; &nbsp; &nbsp; &nbsp; throw new StringIndexOutOfBoundsException(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "begin " + begin + ", end " + end + ", length " + length);&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java