Pregunta Pregunta de manejo de excepciones


Tengo una pregunta sobre el manejo de excepciones. Considere seguir el fragmento de código de Java.

        try{
            //code
        }catch(SubSubException subsubex){
            //code
        }catch(SubException subex){
            //code
        }catch(Exception ex){
            //code
        }

Sé que esta es la forma recomendada de manejar excepciones. Pero puedo lograr lo mismo usando el siguiente fragmento de código.

        try{
            //code
        }catch ( Exception ex){
            if( ex instanceof SubException){              
                //code
            }else if(ex instanceof SubSubException){
                //code
            }else{
                //code
            }
        }

¿Alguien puede decirme las desventajas del segundo enfoque?


31
2018-02-22 05:21


origen


Respuestas:


El segundo enfoque es menos legible. Además, el manejo de excepciones de Pokemon nunca es el camino a seguir, aunque tu truco "inteligente" es usar la palabra clave instanceof. No me estoy burlando ni burlando de todos modos, pero es mejor escribir un código para que los humanos lo lean y lo mantengan, no para la computadora.


110
2018-02-22 05:24



Sí, MadMurf señala la diferencia más importante: verificación de accesibilidad en tiempo de compilación. La expresión estándar capturaría algo como esto y legítimamente evitaría que se compilara:

    try {
    } catch (IndexOutOfBoundsException iooe) {
    } catch (ArrayIndexOutOfBoundsException aiooe) {
    }

Se compilará el if / instanceof analógico propuesto en la pregunta original (que NO es lo que querría porque es erróneo).

La razón por la cual la expresión estándar detecta el error en el momento de la compilación aparece en JLS 14.21 Declaraciones inalcanzables.

  • Un bloque catch C es alcanzable si ambos de los siguientes son verdaderos:      
    • [...]
    • No hay un bloque de captura anterior A en la instrucción try de modo que el tipo de parámetro de C sea el mismo o una subclase del tipo del parámetro de A.

Para ilustrar mejor el punto, las siguientes compilaciones:

    try {
    } catch (Exception e) {
        if (e instanceof Exception) {
        } else if (e instanceof Exception) {
        }
    }

Como puede ver, este modismo de "captura de pokemon" es mucho más difícil de mantener porque elude algo de la verificación de accesibilidad en tiempo de compilación impuesta en el idioma estándar.

Para aclarar aún más el punto, ya sea que lo hayas hecho a propósito o no, en realidad reorganizaste el orden en el que marcaste las excepciones en tu pregunta original, un hecho que otros podrían haber pasado por alto fácilmente. Si SubSubException es una subclase de SubException, la segunda condición if NUNCA se evaluará, y su cuerpo es un código efectivamente inalcanzable.

El enfoque if / instanceof es MUY propenso a errores.


39
2018-02-22 08:04



Hmm, ¿por qué tienes que hacer el segundo acercamiento? recuerda esto, a menos que otras opciones sean mejores en términos de rendimiento, legibilidad, etc., debes seguir las convenciones. catch statement fue diseñado originalmente para que manejen la clasificación de los tipos de excepción propios, así que úsalos como es ... ¡solo un pensamiento! ...


22
2018-02-22 05:29



El segundo caso es el código Java perfectamente válido, pero tiene un código Complejidad ciclomática sin agregar ningún valor extra.


4
2018-02-22 05:35



El segundo enfoque es significativamente menos legible porque:

  • requiere más símbolos,

  • requiere una sangría más profunda,

  • no es idiomático

E IMO, el último es el más importante. Deberías escribir tu código de una manera que otros Programadores de Java espero que esté escrito.


4
2018-02-22 05:37



Como un lado al volver a ordenar su "captura" de excepciones en su segundo ejemplo. Si SubSubException amplía SubException, nunca se alcanzará la segunda verificación ...

algo de lo que hay que tener cuidado al ordenar tus capturas ...

aparte de eso, como se menciona en otra parte, la pregunta debería ser ¿por qué intentar la segunda vía cuando la primera funciona, es la norma y es legible?


2
2018-02-22 05:33



Teniendo en cuenta que el código en el primer bloque prueba el tipo de la excepción, prueba la excepción base una vez (en el segundo bit del código estás probando la Excepción base dos veces) y tiene menos sangría (por lo tanto, menos lógica para grok) , mi pensamiento es que el primero es mucho mejor, más fácil de entender, etc.

Desventajas: - Más difícil de entender


1
2018-02-22 05:30



Creo que es mejor (mucho más legible):

 try {    
   .....
 } 
 catch (IndexOutOfBoundsException iooe) {    } 
 catch (ArrayIndexOutOfBoundsException aiooe) {    }
 .....

y

  try {
     .....
  } 
  catch (Exception e) {
     if (e instanceof Exception) {        } else 
     if (e instanceof Exception) {        } else
     .....
  }

1
2017-07-04 19:33