¿Qué es una excepción StringIndexOutOfBoundsException? ¿Cómo puedo arreglarlo?

Resuelto traveller asked hace 54 años • 1 respuestas

Este es mi código:

    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);
}

Es el valor predeterminado que se proporciona en la documentación de Android. Solo cambié la URL.

Este es mi mensaje de error:

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

Durante la depuración, veo que mTextView.setText("Response is: "+ response.substring(0,500));me entregan el mensaje, pero la vista de texto nunca se actualiza y la aplicación falla.

Específicamente, falla aquí dentro del archivo Looper.Java:

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

etiqueta de seguimiento es 0.

Leí que algunos límites de cuerdas están mal pero no puedo encontrar cómo solucionarlo.

traveller avatar Jan 01 '70 08:01 traveller
Aceptado
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 de descripción

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

Razón real

Su código intenta crear una subcadena con

starting index = 0
ending index = 500

aunque la longitud real de la cadena de respuesta es = 28, la longitud de la cadena no es lo suficientemente larga para crear una subcadena de 500 caracteres.

Soluciones:

  1. Validar longitud usando operador ternario?:

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

    Nota: El operador ternario ( ?:) es una expresión corta, if elsepero no es una declaración, lo que significa que no puede ocurrir como una declaración atómica INVALIDporque no hay asignación.

    ((someString.length()>499) ? someString.substring(0,500):"Invalid length");
    
  2. if-elsemejora la visibilidad

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

¿Qué es IndexOutOfBoundsException?

IndexOutOfBoundsExceptiones una subclase de RuntimeExceptionmedia, es una excepción no verificada que se lanza para indicar que un índice de algún tipo (como una matriz, una cadena o un vector) está fuera de rango. Por ejemplo, usando Lista.

como se muestra en la documentación

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

Prevención :

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

Uso del constructor de clases con índice o mensaje de cadena

public IndexOutOfBoundsException() {
    super();
}

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

¿Cuáles son otras variaciones/subclases de IndexOutOfBoundsException?

  • ArrayIndexOutOfBoundsException : esto indica que se ha accedido a una matriz con un índice ilegal. El índice es negativo o mayor o igual que el tamaño de la matriz, por ejemplo

    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
    

Prevención :

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 : lo lanzan los métodos String para indicar que un índice es negativo o mayor que el tamaño de la cadena. Para algunos métodos como el método charAt, esta excepción también se produce cuando el índice es igual al tamaño de la cadena.

    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
    

Prevención :

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

Nota: length() es una función de Stringclase y lengthes un campo asociativo de un array.

¿Por qué ocurren estas excepciones?

  • Uso de índice negativo con arrayso charAtfuncionessubstring
  • BeginIndex es menor 0o endIndex es mayor que la longitud de la cadena de entrada para crear substring o beginIndex es mayor que endIndex
  • Cuando endIndex - beginIndexel resultado es menor que0
  • Cuando la cadena/matriz de entrada está vacía

INFORMACIÓN: Es trabajo de JVM crear el objeto de excepción apropiado y pasarlo al lugar donde ocurrió usando throwla palabra clave como o también puede hacerlo manualmente usando throwla palabra clave.

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

Cómo puedo arreglar esto ?

  1. Analizando StackTrace
  2. Validar la cadena de entrada contra nulidad, longitud o índices válidos
  3. Uso de depuración o registros
  4. Usando el bloque de captura de excepción genérica

1.) Analizando StackTrace

Como se muestra al principio de esta publicación, stacktrace proporciona la información necesaria en los mensajes iniciales sobre dónde sucedió y por qué sucedió, de modo que usted pueda simplemente rastrear ese código y aplicar la solución requerida.

por ejemplo, el motivo StringIndexOutOfBoundsExceptiony luego busque el suyo, package name indicating your class fileluego vaya a esa línea y, teniendo en cuenta el motivo, simplemente aplique la solución

Es una ventaja si estudia la excepción y su causa también en la documentación.

2.) Validar la cadena de entrada contra nulidad, longitud o índices válidos

En caso de incertidumbre cuando no conoce la entrada real, como que la respuesta proviene del servidor (o tal vez sea un error o nada) o del usuario, siempre es mejor cubrir todos los casos inesperados, aunque créanme, a pocos usuarios siempre les gusta presionar. los límites de las pruebas , así que use input!=null && input.length()>0o para índices, puede usar el operador ternario o if-elselas condiciones de verificación de límites

3.) Uso de depuración o registros

Puede probar el entorno de ejecución de su proyecto en modo de depuración agregando puntos de interrupción en su proyecto y el sistema se detendrá allí para esperar su siguiente acción y, mientras tanto, podrá examinar los valores de las variables y otros detalles.

Los registros son como puntos de control, por lo que cuando su control cruza este punto, generan detalles, básicamente son mensajes informativos proporcionados por el sistema o el usuario también puede colocar mensajes de registro usando mensajes Logs o Println.

4.) Uso del bloque de captura de excepción genérica

Try-catchSiempre es útil manejar los bloques, RuntimeExceptionspor lo que puede usar varios catchbloques para manejar sus posibles problemas y brindar los detalles apropiados.

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 ");
}

Referencias adicionales

¿Qué es una NullPointerException y cómo la soluciono?

Pavneet_Singh avatar Oct 12 '2016 19:10 Pavneet_Singh