2012-01-06 17 views
6

Tengo un bloque try - catch que deseo break como un bloque switch pero no encontré una manera recomendada de hacerlo. Estoy obteniendo una gran cantidad de datos en el bloque try - catch y deseo detener la búsqueda en el medio en caso de que se cumpla una determinada condición. Sólo para que funcione, por ahora, he deliberadamente forzado el código para entrar en el bloque de catch:¿Cuál es la mejor manera de forzar un bloque de prueba para romper?

int i=0; 
    try { 
     //--do stuff---- 
     if(//-------is condition met?--------//) 
      i = 1/0; // divide 1 by 0 -- a definite exception 
    } 
    catch (Exception e) {//---------do nothing---------//} 

¿Es seguro hacer esto o debería ir a por otro camino?

EDITAR: Estoy obteniendo algunos datos xml (en realidad, mucho). Dependiendo de la conexión a Internet, debo detener el análisis después de algún tiempo (time-out) en lugar de pasar por toda la transmisión. Paso por bucles pero también hago algunos cálculos más adelante. No tiene sentido calcular con datos incompletos, por lo que preferiría omitir todo.

+5

Esa es una forma terrible: se puede publicar un contexto más completo? Una forma un poco menos mala es usar un bucle "ficticio" y romperlo, lo cual es una tonta expresión en C, pero sospecho que podría haber una mejor manera de estructurar el código por completo. –

+4

Eso es horrible. – SLaks

+0

Estoy de acuerdo con @pst; sin ver un ejemplo más grande (específicamente, ¿qué es lo que intentas omitir?), es difícil responder a esto de manera significativa. –

Respuesta

3

De cualquier break o throw hará lo que usted quiere (y el throw sería preferible, por lo menos tener algo de trazabilidad que WTH que está haciendo.

[editar]

what: try { 
     System.out.println ("before break"); 
     break what; 

     } catch (Exception e) {} 
    } 

[/editar]

+1

También podría usar un goto. – Max

+4

¿Qué es un 'goto'? – KevinDTimm

+0

@Max [No en java] (http://stackoverflow.com/questions/2545103/is-there-a-goto-statement-in-java) –

0

Sólo hay que poner el resto de la ir a buscar si en un bloque con la condición inversa:

//--do stuff---- 
if (!shouldStop) { 
    // continue doing stuff 
} 
0

Mirando por su código

int i=0; 
    try { 
     //--do stuff---- 
     if(//-------is condition met?--------//) 
      i = 1/0; // divide 1 by 0 -- a definite exception 
    } 
    catch (Exception e) {//---------do nothing---------//} 

si no se cumple la condición? a continuación, usted no necesita preocuparse sobre el uso descanso, y

si se cumple la condición, habrá sin duda una excepción, y que se maneja en la captura (aunque usted no está haciendo nada)

9

Este código huele algunos anti-patrones pero sin más contexto no podemos prescribir un mejor diseño. En general, solo debe lanzar una excepción para una condición excepcional en el estado de su programa. Debería especialmente no arrojar una excepción para el flujo de control normal (esperado), en su lugar debe usar declaraciones de flujo de control como bucles (usando break/continue) y return.

Si desea mantener esta estructura (aunque no debería), entonces le sugiero que lanza explícitamente una clase especial de excepción para que quede claro lo que está haciendo, por ejemplo:

public static class ConditionMetException extends Exception { } 

// ... 
try { 
    // do stuff 
    if (/* Is condition met? */) { 
    throw new ConditionMetException(); 
    } 
} catch (ConditionMetException cme) { /* Do nothing. */ } 

Pero de nuevo, Probablemente sea mejor refactorizar para usar un ciclo y el comando integrado break.

+0

El nombre irónico de la excepción debería ser suficiente para indicar que esta es una idea realmente mala de implementar. No me refiero a eso como una crítica a la respuesta (que responde a lo que se pidió de una manera limpia haciendo una excepción específica), sino a la idea en general. Esto nunca debería ser animado. –

+0

-1 Tal vez estoy de mal humor hoy, pero no puedo creer que una sugerencia de arrojar una "ConditionMetException" para algo que no es excepcional y se está utilizando para el control de flujo del programa normal tenga 5 votos ascendentes. – user949300

+0

@ user949300: estuvo de acuerdo, es un consejo terrible pero aún marginalmente mejor que su propia muestra. ¿Que sugieres? – maerics

0

Si no hay otra manera se puede utilizar una etiqueta de bloque

load:{ 
     if(test)//skip the remaining load block 
     break load; 

    } 

lo contrario, podría refactorizar el código de carga en un método diferente y regresar temprano.

1

lanzar una excepción sólo para romper una mala práctica.

Que este trabajo para su situación?

  1. Ponga el código actualmente dentro del intento en otro método, fetchLotsOfData(). Todavía puede lanzar IOException o lo que sea apropiado.
  2. cuando se quiere dejar de hacer su cosa ir a buscar los datos, simplemente volver. Quizás devolviendo cierto/falso o estado para el éxito.

Así que su código final es algo así como

int recordsRead = -1; // -1 means failure 
try { 
    recordsRead = fetchLotsOfData(); 
} 
catch (IOException ioe) { 
    // handle the exception 
} 

// process what you got... 
1

No es el try-catch que usted debe preocuparse por salir de. De lo que puedo decir, que busca hacer algo a lo largo de las líneas de:

try 
{ 
    // do thing 1 

    // do thing 2 

    if (!done) 
    { 
    // do thing 3 

    // do thing 4 

    if (still not done) 
    { 
     // do thing 5 
    } 
    } 
} catch (Exception e) 
{ 

} 

Si eso es lo que estamos tratando de hacer, entonces eso es probablemente la forma en que debe hacerlo (en lugar de tratar de escapar de el try-catch). La otra forma es reducir los bloqueos try-catch para rodear cada tarea individualmente.

Si proporciona más contexto a su pregunta, entonces puede ser posible proporcionar una mejor respuesta.

1

voy a responder a la "IS es una buena idea?" parte de la pregunta: Nº

No es una buena idea utilizar excepciones para implementar el flujo de control esperado. Es posible, pero no esperado, del mismo modo que es posible hacer todas las variables Cadenas e implementar todas sus estructuras de datos en matrices.

Los bloqueos Try son para crear un límite de alcance que tiene ciertas garantías en la terminación (el comportamiento catch y finally). Una visión código mantenedor:

try{ ... }catch(Exception x){} 

tendería muy fuertemente a cualquiera de volver a lanzar x (tal vez envuelto) o eliminar el bloque completo.

Try-bloques no son sobre lo que está dentro su alcance. Para eso están las construcciones estándar de bucle y, para mejor, las funciones. Su pregunta simplemente desaparece si coloca su alcance en una función:

RetVal doStuff(Arg arg){ 
    //--do stuff---- 
    if(//-------is condition met?--------//) 
     return myResult; 
} 
0

No utilice excepciones para el manejo de errores sin excepción. Es probable que sea un antipatrón llamado. Si es así, no sé el nombre.

Aquí es un ejemplo de salir de un bucle cuando se produce una excepción y no utilizar el control de excepciones para llevar a cabo no excepción gestión de errores:

try 
{ 
    while (... whatever ...) 
    { 
    ... do something that might throw a BlammoException. 
    } 
} 
catch (BlammoException exception) 
{ 
    ... handle the exception. 
} 
0

sólo un tiro que sea la excepción que desea pillan ...

boolean stopLoop = false; 
while (!stopLoop) { 
    try { 
     int key = Integer.parseInt(userInput); 
     if (key > cutOff) throw new NumberFormatException();//<--like this 
     else { 
      System.out.println("Good job, your number didn't suck"); 
      //do some stuff... 
      stopLoop = true;//<--End loop after some stuff 
      //some more stuff, or.. 
      if(nomorestuff)break;//<--exit loop 
     } 
    catch (NumberFormatException nfe){ 
     System.err.println("Enter a number less than "+cutOff); 
    } 
}//end while 
Cuestiones relacionadas