2009-05-21 27 views
10

Me pregunto cómo, en la práctica, otros SO tienden a tratar y/o evitar excepciones.Prevención de excepciones contra excepciones de captura en Java

¿En qué situaciones evita las excepciones y cómo? ¿En qué situaciones encuentras excepciones?

que suelo evitar '' NullPointerExceptions (y otros similares) por, bueno, diciendo esencialmente if(foo!=null) {...}

Me parece que en la mayoría de situaciones, esto es menos voluminoso que todo lo que implica el uso de un bloque try-catch.

Uso los bloques try-catch cuando las posibles excepciones son más complejas o más numerosas.

Respuesta

23

En mi opinión, solo tiene sentido evitar una NullPointerException (por ejemplo) cuando una referencia es nula (de nuevo, por ejemplo) realmente representa un estado de programa válido. Si no lo hace, debe no evitar que ocurra, porque en ese caso quiere el programa se muere duro.

En Java en particular, ciertas excepciones que descienden de RuntimeException (como IllegalArgumentException) tienen la intención de señalar errores de programación, condiciones que no deberían ocurrir si su programa es correcto. Intento seguir esto Si estoy escribiendo un método que restringe sus argumentos, no intentaré evitar arrojar una excepción. Lanzaré uno agresivamente.

+1

Tan cierto. El recuento de errores en el mundo se reduciría significativamente si Java y C# tuvieran tipos de referencia no anulables. – erikkallen

11

Si puede evitar excepciones, entonces es una mejor práctica de programación hacerlo. Por ejemplo, cualquier NullPointerException generalmente indica un error de programación, IMO. (Que es una razón por la cual es una RuntimeException.)

Las excepciones son más útiles cuando espera poder detectar una condición de falla en una capa de código, pero no desea manejar la condición de falla allí, sino que un nivel algo mayor de código. Es decir, tiene la intención de arrojar la excepción más de un cuadro en la pila, o en la parte superior de la pila. Las excepciones también son útiles cuando no espera que el programa pueda manejar el problema de manera significativa.

2

Evita las que puedas (NullPointerExceptions, NullReferenceExceptions, etc.).

Captura los que son un poco más difíciles de atrapar (Errores de Sql ... donde pueden estar fuera de tu control pero tienes que limpiar con gracia después de ellos).

1

En general, si es razonable hacerlo, debe intentar evitar la excepción en primer lugar. Con bastante frecuencia, no es razonable o posiblemente imposible (especialmente cuando io en cuestión), pero para eso sirve try/catch. En particular, esto significa que siempre debe verificar sus punteros y sus índices de matriz para evitar NullPointerException y ArrayIndexOutOfBoundsException. A menos que, por supuesto, no haya nada que puedas hacer al respecto y tendrías que volver a lanzarlo de todos modos.

6

Hay three kinds de excepciones.

Las excepciones de tiempo de ejecución siempre se pueden evitar. Solo tienes que programar correctamente.

Las excepciones comprobadas deben ser transformados para el nivel adecuado de abstracción si es posible (no lanzar una excepción de SQL para el usuario si él no sabe/cuidado acerca de las excepciones SQL) o manipulados en el nivel superior (es decir, permiten aparecen) y muestra/registra el mensaje apropiado.

Los errores no deben manipularse en absoluto.

vea el enlace para más detalles sobre cómo prevenir RuntimeExceptions

1

debe capturar todas las excepciones que pueda. NullPointerException s siempre se pueden evitar con una simple declaración if. algunas otras excepciones, como la mayoría de IOException s, son difíciles de prevenir. y además del texto estándar necesario para usar un bloque try/catch, si su clase arroja una excepción, se creará un objeto de esa excepción y se debe recolectar basura ... para que al no arrojar excepciones, también haga que su VM sea más saludable.

2

Quiero que todas mis excepciones viajen hacia arriba, a menos que sean menores, entonces las tragaré (por ejemplo, evitaré que muera una entrada de reclamo porque una función de notificación por correo electrónico generó una NPE ... Me gustaría tragar esa NPE y mantener camionando mientras la carne real del programa no arroje excepciones).

que utiliza este método para obligar a la mayoría de irrecuperable excepciones aún controladas de Java:

http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html

5

excepciones de captura donde se sabe cómo tratar con ellos.

No debe verificar (foo! = Null) en todas partes, compruebe dónde se usa foo por primera vez. Después de eso simplemente usa foo sin verificar. Si foo se vuelve nulo de repente después de haberse asegurado de que no es nulo, tiene grandes problemas. Una excepción es apropiada entonces.

try { 
    foo(); 
} 
catch (FooException e) { 
} 

es un mal olor de código, y se debe evitar

1

En general, utilizo excepciones cuando la excepción debe causar un proceso para abortar. Cuando haga algo sobre el problema y me recupere de alguna manera, trato de evitar que la excepción ocurra.

Me gusta, si se pasa un parámetro a una subrutina y espero razonablemente que sea nulo, lo verificaré nulo. En la vida real, por ejemplo, una Cadena nula a menudo es equivalente a una Cadena de longitud cero, en la que solo escribiré < si (s == nulo) s = ""; >.

Pero si una Cadena nula significa que algo salió mal y deberíamos abandonar todo el proceso y mostrar un tipo de mensaje "Pánico - Abortar - El mundo termina pronto" para el usuario, entonces una excepción es muy práctico. Puede arrojar la excepción hacia lo más profundo de muchas capas de subrutinas, y simplemente atraparla en la parte superior, mostrar el mensaje, y listo.

A menudo creo mis propias excepciones para tales condiciones. Muchos de mis programas están salpicados con código como < lanzan una nueva BadInputException ("Número de cliente no encontrado")> para que salga, muestre un mensaje y salga. Esto realmente ahorra en el anidamiento profundo de los IF y la comprobación constante de los valores de retorno de las subrutinas.

3

Comprobaré los parámetros de entrada al comienzo de un método y arrojaré una IllegalArgumentException si están fuera de lo que debería pasarse al método. La idea es que es un error de programación y debería solucionarse. Mejor ahora que cuando está en el campo. Si en medio de un método recibo una condición inesperada (nulo en una lista, etc.), registraré un mensaje fatal y haré un System.exit (2). De nuevo, esto te obliga a solucionar un problema, simplemente a iniciar sesión y seguir adelante.

1

Lo impido siempre que sea posible, pero veo cosas que el usuario ha impactado, por ejemplo, cuando ingresan el tipo de datos incorrecto. En Java, tengo una clase que escribí que amplía Scanner y sigue pidiendo la entrada adecuada hasta que sea válida. (De CLI)

2

En general, las excepciones deben ser algo excepcional, p. imprevisible o debido a errores de programación. El problema es que hay un par de descisions diseño dudosas en la biblioteca de clases de Java por lo que terminan con expresiones como:

class Foo { 
    static BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); 
    int getInt() throws IOException { 
    int r=0; 
    for(;;) { 
     String s=in.readLine(); 
     try { 
     r=Integer.parseInt(s); 
     break; 
     } 
     catch(NumberFormatException e) { 
     System.out.println("Please enter a valid integer."); 
     } 
    } 
    return r; 
    } 
} 

Es evidente que el código no es perfecto (lanzará una NullPointerException en EOF), pero demuestra el problema del uso de excepciones para cosas que en realidad no son excepcionales.

2

utilizo la siguiente clase en toda mi código para validar y abortar procesamiento:

@Getter 
@Setter 
public class Abort<T> { 

    private boolean abortProcessing; 

    private T response; 
} 

esta manera se puede validar o capturar excepciones de inmediato, registrarlos y devolver el objeto de abortar.

Cuestiones relacionadas