2012-10-07 16 views
5

He estado mirando esto durante horas y sin poder encontrar una solución; Por lo general encargan de la validación de este tipo con expresiones regulares, pero estoy tratando de utilizar una solución integrada para un cambio (obviamente, no hago esto con frecuencia):Java try/catch - ¿"return is not found" o "variable no se ha inicializado"?

private static double promptUserDecimal(){ 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    try{ 
     double input2 = Double.parseDouble(scan.nextLine()); 
     return input2; 
    } catch(NumberFormatException e){ 
     System.out.println("Sorry, you provided an invalid option, please try again."); 
    } 
} 

El error con esto es que el "retorno "no es encontrado por el compilador, así que me sale un error de compilación". Si pongo el "retorno" fuera del try/catch, necesito declarar/inicializar "input2", lo que anula el objetivo de la operación. Se aprecia cualquier ayuda ...

+1

Usted detecta la excepción, imprime un mensaje, pero luego el método continúa desde el bloque' catch'. El compilador se queja del hecho de que no regresa si se golpea el bloque catch (no todos rutas de retorno) – birryree

Respuesta

0

Es necesario devolver o tirar algo a partir de (o después de la captura). A juzgar por su salida para el usuario, parece que solo quiere hacer lo mismo otra vez. Simplemente llame de nuevo al método y devuelva el resultado.

private static double promptUserDecimal(){ 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    try{ 
     double input2 = Double.parseDouble(scan.nextLine()); 
     return input2; 
    } catch(NumberFormatException e){ 
     System.out.println("Sorry, you provided an invalid option, please try again."); 
     return promptUserDecimal(); 
    } 
} 
+0

El uso de recursividad para "intentar de nuevo" es al poco extraño; creará más llamadas pendientes en la pila cada vez. Aunque es poco probable que el usuario ingrese una entrada incorrecta lo suficiente como para causar un desbordamiento de la pila, un bucle tendría más sentido. – Wyzard

1

Deje que su método arroje una excepción o devuelva a nan.

3

Lanza una excepción en la sección catch. Dondequiera que se llama al método promptUserDecimal, la captura de cualquier excepción y no imprimir el mensaje:

public static void main(String[] args) { 

    double d = 0.0; 
    while (double == 0) { 
     try { 
      d = promptUserDecimal(); 
     } catch (NumberFormatException e) { 
      //log the message... 
      d = 0.0; 
     } 
    } 
} 

private static double promptUserDecimal() throws NumberFormatException { 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    return Double.parseDouble(scan.nextLine()); 
} 

Este sería un enfoque mejor porque deja que los promptUserDecimal sólo se preocupa por el manejo de la lectura de un valor doble. Debe tratar de separar cada clase y método para el propósito específico para el que fue diseñado.

+0

+1 pero si va a tirar 'NumberFormatException' de todos modos, entonces no es necesario que lo atrape. No lo atrape en primer lugar, deje' parseDouble' lanzar la excepción. –

+0

@ user1598390 verdadero de hecho. Respuesta actualizada. –

3

Usted necesita algo así como:

double input2; 
try{ 
    //read input2 
}catch(...){ 
    //... log AND assign a value to input2 in case of invalid input 
} 
return input2; 
+0

Puede asignar el valor de error predeterminado al declarar la variable –

0

Usted puede lanzar una excepción dentro de su bloque catch. es decir,

private static double promptUserDecimal() throws OopsException { 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    try{ 
     double input2 = Double.parseDouble(scan.nextLine()); 
     return input2; 
    } catch(NumberFormatException e){ 
     System.out.println("Sorry, you provided an invalid option, please try again."); 
     throw new OopsException(); 
    } 
} 

Entonces, cada vez que dan una entrada no válida, se puede coger y manejarlo cuando se llama al método de.

0
private static double promptUserDecimal(){ 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    double input2 = 0.0; // <-- explicit initialization 
    try{ 
     double input2 = Double.parseDouble(scan.nextLine()); 
    } catch(NumberFormatException e){ 
     System.out.println("Sorry, you provided an invalid option, please try again."); 
    } 
    return input2; 
} 
3

Si desea que el usuario "por favor intente de nuevo", suena como que necesita un bucle:

private static double promptUserDecimal(){ 
    final Scanner scan = new Scanner(System.in); 

    // Ask for input until we get something valid 
    while (true) { // Terminated by return within 
     System.out.println("Enter a decimal"); 
     try { 
      return Double.parseDouble(scan.nextLine()); 
     } catch(NumberFormatException e){ 
      System.out.println("Sorry, you provided an invalid option, please try again."); 
      // No return, so the loop will run again 
     } 
    } 
} 
+1

Tengo una pregunta. Este fragmento compila? –

+0

@PaulVargas, compila para mí. ¿Ves un error en él? – Wyzard

+0

OP: I como esta solución para un script desatendido. – user1612272

0

Algunas de las soluciones que se indican va a resolver el problema del compilador, pero el primer paso es tomar un paso atrás y preguntar "¿qué es lo que quiero hacer en el caso de que se produzca un NumberFormatException?"

Una opción es propagar la excepción volviendo a lanzar NumberFormatException o envolviéndola en una RuntimeException para que no se verifique. Esto significa que el código de llamada tendrá que manejarlo, o se le presentará al usuario una stacktrace. Si vas por esta ruta, ni siquiera necesitas una captura de prueba en tu método. Puede declarar "throws NumberFormatException" en la firma del método y dejar que se maneje en la secuencia.

Otra opción es devolver nulo, ya sea usando "return null" como la última instrucción en tu catch block, o devolviendo null como la última instrucción dentro del método. Esta es una opción terrible porque el código de llamada y/o el usuario final no obtendrán la información que necesitan, que "se ingresó un no número como entrada".

Me gustaría ir con la opción uno, y manejar la excepción diciéndole al usuario que scan.nextline + "no se reconoce como un doble válido."

Cuestiones relacionadas