亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 字符串索引越界異常

Java 字符串索引越界異常

揚帆大魚 2022-08-03 10:09:19
是的,我知道如何解決這個問題。我正在研究字符串類和字符串生成器類之間的API。以下是我的問題:StringBuilder sb = new StringBuilder("wibble");String s = new String("wobble");sb.charAt(index) //Can throw Index Out Of Bounds Exceptions.charAt(index) //Can throw Index Out of Bounds Exceptionsb.substring(start, end) //Can throw STRING index out of bounds exceptions.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() 相同
查看完整描述

2 回答

?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

這取決于您使用的 JDK 實現。

我做了一些挖掘,找到了該類的實現方法(注意:我使用的是Oracle JDK 1.8)。public char charAt(int index)StringBuilder

因此,在本例中,該類是 的子類。這是實現程序員的選擇,因為你不會在文檔中找到它。StringBuilderAbstractStringBuilder

我發現該函數是在基類上實現的。以下是來自我的系統的相關代碼的一些屏幕截圖。(請記住,特定的JDK是Oracle和Java 1.8)。charAtAbstractStringBuilder


http://img1.sycdn.imooc.com//62e9d8eb000112df04010101.jpg

http://img1.sycdn.imooc.com//62e9d8f30001305908010425.jpg

更新

我實際上運行了一些代碼來測試拋出的異常,并發現了一些有趣的東西。我的環境中的函數還拋出了一個 .以下是我運行以測試它的代碼:charAt()java.lang.StringIndexOutOfBoundsException


public 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.StringIndexOutOfBoundsException

Exception encountered accessing character out of index bounds on variable 'string': class java.lang.StringIndexOutOfBoundsException


Process finished with exit code 0

要解決評論中的一些問題:

  • [AbstractStringBuilder]不在文檔中,這意味著我們不能用它編寫程序?

    一個通常跟隨另一個。該類是包的私有類,這意味著無法從該包的外部訪問它。這意味著您將無法在代碼中導入和使用此類。這是一個完美的例子,說明某些不屬于系統公共API的代碼部分(在本例中是JDK本身),在這種情況下,由于以下幾個原因,它不會被記錄:AbstractStringBuilderjava.lang

    1. 您不能使用它

    2. 實施細節可能會不斷變化

    3. 它不應影響公共API(系統的記錄部分)的使用

  • 如果在拋出一個,那么為什么文檔說簡單?charAt()StringBuilderStringIndexOutOfBoundsExceptionIndexOutOfBoundsException

    這是因為這是基于類的設計意圖所描述的函數行為。由于您可以為異常創建任意數量的子類(就像任何其他不是的Java類一樣),因此始終由實現程序員選擇最好從函數返回(或拋出)的內容,只要函數遵守商定的契約(接口,文檔規范,抽象類, 等)。charAt()final

    話雖如此,您現在可以實現JDK,并選擇自己的子類來投放此場景。如果我在我的代碼中使用,我會捕獲文檔中描述的異常,因為這將允許我獲得最大的靈活性/可移植性,而不會因依賴實現細節而中斷風險。關于這個主題已經寫了整本書,所以我將把討論留在這里:總是嘗試捕捉你知道可能被拋出的最具體的異常,這意味著,如果其他實現可能不會拋出,那么你最好抓住,因為它保證是該類型(或它的子類)。IndexOutOfBoundsExceptionStringBuilder.charAt()StringOutOfBoundsExceptionIndexOutOfBoundsException

更新 2

在這種特定情況下,您幾乎可以忽略我上面提到的所有內容,而只關注以下內容:

charAt()是 java.lang.CharSequence 中描述的一種接口方法。這意味著對于任何實現類,當嘗試訪問超出序列邊界的索引時,引發的問題將是 .該接口描述了一般行為,并且沒有必要用 、 a 、 an 或任何其他特定實現來定義此行為。如果這些暗示。決定對該異常進行子類化,并在每種情況下提供更具體的錯誤信息,這很好,但它不會更改總協定。如果您正在編寫通用字符處理系統,那么您可能會寫入接口而不關心底層 impl。在這種情況下,你只會知道(或關心)什么都沒有。IndexOutOfBoundsExceptionStringStringBuilderAlphabetSoupIndexOutOfBoundsException


查看完整回答
反對 回復 2022-08-03
?
絕地無雙

TA貢獻1946條經驗 獲得超4個贊

這似乎是一個文檔拼寫錯誤。


在 Java HotSpot(TM) 10.0.1 中,確實拋出了 :String.substringStringIndexOutOfBoundsException


public String substring(int beginIndex, int endIndex) {

    int length = length();

    checkBoundsBeginEnd(beginIndex, endIndex, length); //here

    int subLen = endIndex - beginIndex;

    if (beginIndex == 0 && endIndex == length) {

        return this;

    }

    return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)

                      : StringUTF16.newString(value, beginIndex, subLen);

}



static void checkBoundsBeginEnd(int begin, int end, int length) {

    if (begin < 0 || begin > end || end > length) {

        throw new StringIndexOutOfBoundsException(

            "begin " + begin + ", end " + end + ", length " + length);

    }

}


查看完整回答
反對 回復 2022-08-03
  • 2 回答
  • 0 關注
  • 160 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號