什么是 StringIndexOutOfBoundsException?我该如何解决? [英] What is a StringIndexOutOfBoundsException? How can I fix it?

查看:48
本文介绍了什么是 StringIndexOutOfBoundsException?我该如何解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:

 私有无效带来数据(){final TextView mTextView = (TextView) findViewById(R.id.textView);//实例化请求队列.RequestQueue 队列 = Volley.newRequestQueue(this);字符串 url ="http://192.168.4.1:8080/";//从提供的 URL 请求字符串响应.StringRequest stringRequest = new StringRequest(Request.Method.GET, url,新的 Response.Listener() {@覆盖公共无效onResponse(字符串响应){//显示响应字符串的前 500 个字符.mTextView.setText("响应为:"+ response.substring(0,500));}}, 新的 Response.ErrorListener() {@覆盖公共无效onErrorResponse(VolleyError错误){mTextView.setText("那没用!");}});//将请求添加到RequestQueue.queue.add(stringRequest);}

这是 android 文档中给出的默认值.我只更改了网址.

这是我的错误信息:

<块引用>

java.lang.StringIndexOutOfBoundsException: length=28;regionStart=1;区域长度=499在 java.lang.String.substring(String.java:1931)在 com.example.my.app.MainActivity$2.onResponse(MainActivity.java:50)在 com.example.my.app.MainActivity$2.onResponse(MainActivity.java:46)在 com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)在 com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)在 com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)在 android.os.Handler.handleCallback(Handler.java:751)在 android.os.Handler.dispatchMessage(Handler.java:95)在 android.os.Looper.loop(Looper.java:154)在 android.app.ActivityThread.main(ActivityThread.java:6077)在 java.lang.reflect.Method.invoke(Native Method)在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

在调试过程中,我看到 mTextView.setText("Response is: "+ response.substring(0,500)); 我的消息已发送给我,但 textview 从未更新并且应用程序崩溃.

具体来说,它在 Looper.Java 文件中崩溃了:

最后{如果(跟踪标签!= 0){Trace.traceEnd(traceTag);}

traceTag 为 0.

我读到某些字符串边界是错误的,但我不知道如何修复它.

解决方案

错误信息:java.lang.StringIndexOutOfBoundsException: length=28;regionStart=1;regionLength=499 在 java.lang.String.substring(String.java:1931) 在com.example.my.app.MainActivity$2.onResponse(MainActivity.java:50) 在com.example.my.app.MainActivity$2.onResponse(MainActivity.java:46) 在com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60) 在com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30) 在com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99) at android.os.Handler.handleCallback(Handler.java:751) atandroid.os.Handler.dispatchMessage(Handler.java:95) 在android.os.Looper.loop(Looper.java:154) 在android.app.ActivityThread.main(ActivityThread.java:6077) 在java.lang.reflect.Method.invoke(Native Method) 在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

错误描述

您的 MainActivity 类中发生了 IndexOutOfBound 异常在第二个内部类的 OnResponse 函数中,如图所示 MainActivity$2onResponse在第 46 行,它基本上发生在 String.java 行 1931 中的子字符串操作期间在第 60 行从 StringRequest.deliverResponse 调用,在第 30 行从 StringRequest.deliverResponse 调用,它是从 ExecutorDelivery.java 第 99 行调用的,最初从 ZygoteInit$MethodAndArgsCaller 的运行函数开始并到达 ActivityThread.main=>looper=>handler 的主线程

实际原因

您的代码尝试使用

创建子字符串

起始索引 = 0结束索引 = 500

尽管您的实际响应字符串长度为 = 28,但字符串长度不足以创建 500 个字符的子字符串.

解决方案:

  1. 使用三元运算符?:

    验证长度

    mTextView.setText("响应为:"+((response.length()>499) ? response.substring(0,500) : "长度太短"));

    注意:三元运算符 (?:) 是 if else 的简短表达式,但它是 不是语句 意味着它不能作为原子语句出现,因为这是INVALID 因为没有赋值

    ((someString.length()>499) ? someString.substring(0,500):"无效长度");

  2. if-else 增强可见性

    String msg="无效响应";如果(响应.长度()> 499){msg=response.substring(0,500);}mTextView.setText("响应为:"+msg);//或 mTextView.setText("响应为:"+响应);

什么是 IndexOutOfBoundsException?

<块引用>

IndexOutOfBoundsExceptionRuntimeException 的子类,意思是这是一个未经检查的异常,它被抛出以表明一个索引某种类型(例如数组、字符串或向量)已失效范围的.例如使用列表.

文档中所示/p><块引用>

Listls=new ArrayList();ls.add("a");ls.add("b");ls.get(3);//将抛出 IndexOutOfBoundsException ,列表长度为 2

预防:

String str = "";整数索引=3;if(index < ls.size())//检查,列表大小必须大于索引str = ls.get(index);别的//打印无效的索引或其他东西

带索引或字符串消息的类构造函数使用

public IndexOutOfBoundsException() {极好的();}公共 IndexOutOfBoundsException(String s) {超级(S);}

IndexOutOfBoundsException 的其他变体/子类有哪些?

  • ArrayIndexOutOfBoundsException :这表明已使用非法索引访问了数组.索引为负数或大于或等于数组的大小,例如

    <块引用>

    int arr = {1,2,3}int 错误 = arr[-1];//不允许负索引int error2 = arr[4];//arr 长度为 3,因为索引范围为 0-2

预防:

int num = "";整数索引=4;if(index < arr.length)//检查,数组长度必须大于索引数字 = arr[索引];别的//打印无效的索引或其他东西

  • StringIndexOutOfBoundsException :这是由 String 方法抛出的,以指示索引为负数或大于字符串的大小.对于一些方法比如charAt方法,当索引等于字符串的大小时也会抛出这个异常.

    <块引用>

    String str = "foobar";//长度 = 6字符错误 = str.charAt(7);//索引输入应该小于或等于length-1字符错误 = str.charAt(-1);//不能使用负索引

预防:

String name = "FooBar";整数索引 = 7;字符持有者 = '';if(index < name.length())//检查,字符串长度必须大于索引持有人 = name.charAt(index) ;别的//打印无效的索引或其他东西

注意: length()String 类的函数,length数组.

为什么会出现这些异常?

  • 负索引与arrayscharAtsubstring函数的使用
  • BeginIndex 小于 0 或 endIndex 大于输入字符串的长度以创建 substring 或 beginIndex 大于 endIndex
  • endIndex - beginIndex 结果小于 0
  • 当输入的字符串/数组为空时

INFO : JVM 的工作是创建适当的异常对象并将其传递到发生的地方,使用 throw 关键字 like 或者您也可以也可以使用 throw 关键字手动完成.

if (s == null) {throw new IndexOutOfBoundsException("null");}

我该如何解决这个问题?

  1. 分析堆栈跟踪
  2. 根据空值、长度或有效索引验证输入字符串
  3. 使用调试或日志
  4. 使用通用异常捕获块

1.) 分析 StackTrace

如本文开头所示,stacktrace 在初始消息中提供了有关发生位置、发生原因的必要信息,因此您可以简单地跟踪该代码并应用所需的解决方案.

例如StringIndexOutOfBoundsException 的原因,然后查找您的包名称指示您的类文件 然后转到该行并记住原因,只需应用解决方案

如果您在文档中研究异常及其原因,这是一个良好的开端.

2.) 根据空值、长度或有效索引验证输入字符串

在不确定的情况下,当您不知道响应来自服务器(或者可能是错误或什么都没有)或用户的实际输入时,那么最好涵盖所有意外情况尽管相信我很少有用户总是喜欢挑战测试的极限,所以使用 input!=null &&input.length()>0 或者对于索引,可以使用三元运算符或者if-else边界检查条件

3.) 使用调试或日志

您可以通过在项目中添加断点来在调试模式下测试项目的运行环境,系统会停在那里等待您的下一步操作,同时您可以查看变量的值和其他细节.

>

日志就像检查点,所以当你的控件跨越这一点时,它们会生成详细信息,基本上它们是由凋零系统提供的信息性消息,或者用户也可以使用日志或 Println 消息放置日志消息

4.) 使用通用异常捕获块

Try-catch 块对于处理 RuntimeExceptions 总是有用的,因此您可以使用多个 catch 块来处理您可能出现的问题并给出适当的细节

尝试{mTextView.setText("响应为:"+ response.substring(0,500));} catch (IndexOutOfBoundsException e) {e.printStackTrace();System.out,println("无效索引或空字符串");}catch (NullPointerException e) {//mTextView 或响应可以为空e.printStackTrace();System.out,println("出了点问题,错过了初始化");}捕获(异常 e){e.printStackTrace();System.out,println("发生了意想不到的事情,继续前进或可以看到堆栈跟踪");}

进一步参考

什么是 NullPointerException,我该如何处理解决了吗?

This is my code:

    private void bringData() {
    final TextView mTextView = (TextView) findViewById(R.id.textView);

    // Instantiate the RequestQueue.
    RequestQueue queue = Volley.newRequestQueue(this);
    String url ="http://192.168.4.1:8080/";

    // Request a string response from the provided URL.
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    // Display the first 500 characters of the response string.
                    mTextView.setText("Response is: "+ response.substring(0,500));
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            mTextView.setText("That didn't work!");
        }
    });
    // Add the request to the RequestQueue.
    queue.add(stringRequest);
}

It's the default given from the android documentation. I only changed the url.

This is my error message:

java.lang.StringIndexOutOfBoundsException: length=28; regionStart=1; regionLength=499 at java.lang.String.substring(String.java:1931) at com.example.my.app.MainActivity$2.onResponse(MainActivity.java:50) at com.example.my.app.MainActivity$2.onResponse(MainActivity.java:46) at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60) at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30) at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

During debugging I see that at mTextView.setText("Response is: "+ response.substring(0,500)); my message is delivered to me but the textview is never updated and the app crashes.

Specifically, it crashes here inside the Looper.Java file:

finally {
if (traceTag != 0) {
   Trace.traceEnd(traceTag);
} 

traceTag is 0.

I read that some string bounds are wrong but I cannot find out how to fix it.

解决方案

Error Message:
    java.lang.StringIndexOutOfBoundsException: length=28; regionStart=1;
    regionLength=499 at java.lang.String.substring(String.java:1931) at     
    com.example.my.app.MainActivity$2.onResponse(MainActivity.java:50) at     
    com.example.my.app.MainActivity$2.onResponse(MainActivity.java:46) at     
    com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60) at     
    com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30) at     
    com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99) at android.os.Handler.handleCallback(Handler.java:751) at     
    android.os.Handler.dispatchMessage(Handler.java:95) at     
    android.os.Looper.loop(Looper.java:154) at     
    android.app.ActivityThread.main(ActivityThread.java:6077) at     
    java.lang.reflect.Method.invoke(Native Method) at     
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) at     
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

Error Description

There is an IndexOutOfBound exception occurred in your MainActivity class 
Inside second inner class's OnResponse function as shown MainActivity$2onResponse
on line 46 which basically occurred during substring operation in String.java line 1931 
which was invoked from StringRequest.deliverResponse at line 60,
which was invoked from StringRequest.deliverResponse at line 30,
which was invoked from ExecutorDelivery.java at line 99,
which intially started from ZygoteInit$MethodAndArgsCaller's run function 
and reached up-to main thread of ActivityThread.main=>looper=>handler

Actual Reason

Your code trying to create a substring with

starting index = 0
ending index = 500

though your actual response string length is = 28, so String length is not long enough to create a substring of 500 characters.

Solutions :

  1. Validate length using ternary operator ?:

    mTextView.setText("Response is: "+ 
       ((response.length()>499) ? response.substring(0,500) : "length is too short"));
    

    Note : Ternary operator (?:) is a short expression of if else but it is not a statement mean it cannot occur as an atomic statement as this is INVALID because there is no assignment

    ((someString.length()>499) ? someString.substring(0,500):"Invalid length");
    

  2. if-else enhances the visibility

    String msg="Invalid Response";
    if(response.length()>499){
        msg=response.substring(0,500);
    }
    mTextView.setText("Response is: "+msg);
    
    //or     mTextView.setText("Response is: "+response);
    

What is IndexOutOfBoundsException?

IndexOutOfBoundsException is a subclass of RuntimeException mean it is an unchecked exception which is thrown to indicate that an index of some sort (such as to an array, to a string, or to a vector) is out of range.e.g using List.

as shown in the Documentation

List<String> ls=new ArrayList<>();
      ls.add("a");
      ls.add("b");
      ls.get(3); // will throw IndexOutOfBoundsException , list length is 2

Prevention :

String str = "";
int index =3; 
if(index < ls.size())    // check, list size must be greater than index
    str = ls.get(index);
else
    // print invalid index or other stuff

Class Constructor usage with index or string message

public IndexOutOfBoundsException() {
    super();
}

public IndexOutOfBoundsException(String s) {
    super(s);
}

Which are other variations/sub-classes of IndexOutOfBoundsException?

  • ArrayIndexOutOfBoundsException : This indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array for e.g

    int arr = {1,2,3}
    int error = arr[-1]; // no negative index allowed
    int error2 = arr[4]; // arr length is 3 as index range is 0-2
    

Prevention :

int num = "";
int index=4;
if(index < arr.length)     // check, array length must be greater than index
    num = arr[index];
else
    // print invalid index or other stuff

  • StringIndexOutOfBoundsException : This is thrown by String methods to indicate that an index is either negative or greater than the size of the string. For some methods such as the charAt method, this exception also is thrown when the index is equal to the size of the string.

    String str = "foobar";       // length = 6
    char error = str.charAt(7);  // index input should be less than or equal to length-1
    char error = str.charAt(-1); // cannot use negative indexes
    

Prevention :

String name = "FooBar";
int index = 7;
char holder = '';
if(index < name.length())     // check, String length must be greater than index
    holder = name.charAt(index) ;
else
    // print invalid index or other stuff

Note: length() is a function of String class and length is a associative field of an array.

Why these exception occur?

  • Usage of Negative index with arrays or charAt , substring functions
  • BeginIndex is less than 0 or endIndex is greater than the length of input string to create substring or beginIndex is larger than the endIndex
  • When endIndex - beginIndex result is less than 0
  • When input string/array is empty

INFO : It is job of JVM to create the object of appropriate exception and pass it to the place of , where it occurred using throw keyword like or you can also do it manually using throw keyword too.

if (s == null) {
    throw new IndexOutOfBoundsException("null");
}

How can I fix this ?

  1. Analyzing StackTrace
  2. Validating input string against nullity , length or valid indexes
  3. Using Debugging or Logs
  4. Using Generic Exception catch block

1.) Analyzing StackTrace

As shown at the beginning of this post , stacktrace provides the necessary information in the initial messages about where it happen , why it happen so you can simply trace that code and apply the required solution .

for e.g the reason StringIndexOutOfBoundsException and then look for your package name indicating your class file then go to that line and keeping the reason in mind , simply apply the solution

It's a head start if you study about the exception and its cause as well in documentation.

2.) Validating input string against nullity , length or valid indexes

In case of uncertainty when you don't know about the actual input like response is coming from server (or maybe it's an error or nothing) or user then it's always better to cover all the unexpected cases though believe me few users always like to push the limits of testing so use input!=null && input.length()>0 or for indexes, you can use the ternary operator or if-else boundary check conditions

3.) Using Debugging or Logs

You can test the running environment of your project in debug mode by adding break-points in your project and system will stop there to wait for your next action and meanwhile you can look into the values of variables and other details.

Logs are just like check-points so when your control cross this point they generate details , basically they are informative messages given by wither system or user can also put logging messages using either Logs or Println messages

4.) Using Generic Exception catch block

Try-catch blocks are always useful to handle RuntimeExceptions so you can use multiple catch block along to handle your possible issues and to give appropriate details

try {
     mTextView.setText("Response is: "+ response.substring(0,500));
} catch (IndexOutOfBoundsException e) {
    e.printStackTrace();
    System.out,println("Invalid indexes or empty string");
}
  catch (NullPointerException e) { // mTextView or response can be null 
    e.printStackTrace();
    System.out,println("Something went wrong ,missed initialization");
}
catch (Exception e) {  
    e.printStackTrace();
    System.out,println("Something unexpected happened , move on or can see stacktrace ");
}

Further References

What is a NullPointerException, and how do I fix it?

这篇关于什么是 StringIndexOutOfBoundsException?我该如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆