2011-09-27 28 views
9

Tengo una oportunidad con varias capturas diferentes después. Tengo un código de "limpieza" que solo debe ejecutarse si se lanza una excepción. Podría agregar el mismo código a cada excepción, pero eso se convierte en una pesadilla de mantenimiento. Básicamente, me gustaría algo como la declaración final, pero para que solo se ejecute si se lanzó una excepción.¿Cómo hacer que el código se ejecute solo si se lanzó una excepción?

¿Esto es posible?

+0

Son estos errores de tiempo de ejecución que está atrapando o sus propios errores de negocios. – Shahzeb

+0

IOException, ClientProtocolException, UnsupportedEncodingException, etc. – Bromide

Respuesta

18

Desafortunadamente, no hay soporte directo para esto. ¿Qué tal algo como esto

boolean successful = false; 
try { 
    // do stuff 
    successful = true; 
} catch (...) { 
    ... 
} finally { 
    if (!successful) { 
     // cleanup 
    } 
} 
1

Lo único que puedo pensar es establecer una variable en cada captura y para verificar si esa variable en fin.

Pseudocódigo:

Boolean caught = false; 

try { 

    //risky code here 

catch(err) { 
    caught = true; 
    // Do other stuff 
} 
catch(err) { 
    caught = true; 
    // Do other stuff 
} 
catch(err) { 
    caught = true; 
    // Do other stuff 
} 
finally { 
    if (caught) { 
     // Do clean up 
    } 

} 
0

¿Por qué no sólo tiene que utilizar sencilla intento de captura &?

try 
{ 
    foo(); 
} 
catch(Exception1 e1) 
{ 
    dealWithError(1); 
} 
catch(Exception2 e2) 
{ 
    dealWithError(2); 
} 
catch(Exception3 e3) 
{ 
    dealWithError(3); 
} 

... 

private void dealWithError(int i) 
{ 
    if(i == 1) // deal with Exception1 
    else if(i == 2) // deal with Exception2 
    else if(i == 3) // deal with Exception3 
} 
+2

exactamente lo que ningún cuerpo debería hacer. Pesadilla en la calle 'si'. – Shahzeb

1

podría añadir el mismo código para cada una excepción, sino que se convierte en una pesadilla de mantenimiento.

O si borrar el 'excepción':

podría añadir el mismo código para cada [lugar], pero que se convierte en una pesadilla de mantenimiento.

Esto es para lo que están hechos los métodos.

private void cleanup() { /* clean up */ } 

... 

try { 
    // oh noes 

} catch (MyException me) { 
    cleanup(); 
} catch (AnotherException ae) { 
    cleanup(); 
} 

Maintenance hassle gone!

+2

Excepto que ahora no tiene acceso a las cosas que están dentro de la persona que llama. Si eso es lo que necesita limpieza, eres una manguera. Y si pasa las cosas desordenadas, entonces está codificando la lista de cosas para arreglar, y si esa lista cambia más adelante, debe cambiar cada lugar que la use. Y te perderás uno. – cHao

+0

Ah, y esta función 'cleanup' debería * definitivamente * ser' private', si insistes en tenerla. – cHao

+0

@cHao Mientras ture y finalmente es más agradable, si se pierde un lugar, el código simplemente no se compilará, por lo que aún es menos malo – Voo

0

Usted podría tratar de envolver dos capas de controladores de excepciones, y volver a lanzar la excepción después de haber hecho un tratamiento común:

try { 
     try { 
      // your code goes here 

     } catch (Throwable t) { 
      // do common exception handling for any exception 
      throw t; 
     }  

    } catch (NullPointerException nx) { 
     // handle NPE 
    } catch (Throwable t) { 
     // handle any other exception 
    } 

No estoy seguro de que realmente me gusta esta solución, aunque ... se siente como un poco de una cortar. Probablemente preferiría ver la excepción manejada explícitamente en cada instancia, incluso si esto significa repetir una llamada a algún tipo de función de limpieza compartida.

Cuestiones relacionadas