8

¿Podría alguien darme una pista de por qué esta prueba y captura no funciona? Lanza una excepción de escáner en lugar de imprimir el mensaje que espero.Probar/atrapar en Java

import java.util.*; 
import java.io.*; 
import java.math.*; 
import javax.swing.*; 

public class Main { 
    public static void main(String[] args) { 
     Boolean test = true; 
     while (test == true) { 
      try { 
       double x, y; 
       String operator; 
       Scanner scan = new Scanner(System.in); 
       Scanner scan_2 = new Scanner(System.in); 
       Scanner ScanOperator = new Scanner(System.in); 
       System.out.println(" Enter a double value: "); 
       x = scan.nextDouble(); 
       System.out.println(" Enter another double value: "); 
       y = scan_2.nextDouble(); 
       System.out.println(" Enter a operator for the operation you want to execute, or X if you want to quit: "); 
       operator = ScanOperator.nextLine(); 
       if (operator.equals("x") || operator.equals("X")) { 
        test = false; 
        System.out.println("No calculation was made!!!"); 
       } 
       System.out.println(Calculation(operator, x, y)); 
      } catch (NumberFormatException nfe) { 
       JOptionPane.showMessageDialog(null,"Input must be a number."); 
      } 
     } 
    } 

    public static double Calculation(String operator, double x, double y) { 
     double result = 0; 
     double myAdd = 0; 
     double mySub = 0; 
     double myMult = 0; 
     double myDiv = 0; 
     double myPower = 0; 
     double myMod = 0; 

     if (operator.equals("+")) { 
      myAdd = x + y; 
      result = myAdd; 
     } else if (operator.equals("-")) { 
      mySub = x - y; 
      result = mySub; 
     } else if (operator.equals("*")) { 
      myMult = x * y; 
      result = myMult; 
     } else if (operator.equals("/")) { 
      myDiv = x/y; 
      result = myDiv; 
     } else if (operator.equals("^")) { 
      myPower = Math.pow(x, y); 
      result = myPower; 
     } else if (operator.equals("%")) { 
      myMod = x % y; 
      result = myMod; 
     } else { 
     } 

     return result; 
    } 
} 
+0

¿Qué le dice la excepción? – nos

+0

Este código está bien. Puedo ejecutarlo tal como es localmente. – Thunderhashy

Respuesta

1

Has encontrado la excepción incorrecta.

4

Está intentando capturar una excepción NumberFormatException. Necesita agregar una declaración catch para una ScannerException, ya que es diferente de NumberFormatException.

+0

No hay ScannerException en Java – Thunderhashy

2

Necesita detectar ScannerException o algo como esto.

En este código, solo está obteniendo el NumberFormatException.

Pruebe algunos como esto:

try { 
     ... 
    } catch (NumberFormatException, ScannerException exception) { 
     JOptionPane.showMessageDialog(null,"Input must be a number."); 
    } 
+0

Perdóneme si me equivoco, pero no debería ser: 'catch (NumberFormatException, ScannerException e) {' – zmbush

+0

Tiene razón. Mi error. =) –

+0

¿cómo podemos capturar 2 excepciones en el mismo bloque catch? – Thunderhashy

21

simple, el programa de tiros ScannerException, pero su intento de captura sólo puede coger NumberFormatException, es necesario agregar otra cláusula catch con el fin de atrapar ScannerException, o coger sólo el genérico Excepción.

por ejemplo, cuando dicen:

} catch (NumberFormatException nfe) {  
    JOptionPane.showMessageDialog(null,"Input must be a number."); 
} 

que sólo se especifica cómo atrapar NumberFormatException.
Con el fin de capturar todas las excepciones, lo que se necesita para que sea:

} catch (NumberFormatException nfe) {  
    JOptionPane.showMessageDialog(null,"Input must be a number."); 
}catch (Exception e){ 
    JOptionPane.showMessageDialog(null,"Generic exception caught"); 
} 

En este caso, el segundo retén conseguiría todo lo que no fue capturado en la primera captura, porque todas las excepciones se extienden a la clase de excepción, se puede atrapar todas las clases derivadas con esa declaración.

Sin embargo, desde la captura de excepciones por sí mismo no es bien vista, se podría también hacer:

} catch (NumberFormatException, ScannerException e) {  
    JOptionPane.showMessageDialog(null,"Input must be a number."); 
} 

Para la captura de los dos excepciones en el mismo bloque.

+1

Aunque recomendaría capturar la excepción específica que desea capturar, en este caso una excepción de escáner, en lugar de una captura de excepción general. Pero esto es correcto. – aperkins

+0

gracias. ¡Fue realmente útil! – Tony

+0

Mi favorito personal es catch (Throwable t) – Andres

0

Su código no lanzará un NumberFormatException. Debería tomar un InputMismatchException en su lugar.

En cuanto a nextDouble, en Scanner, parece que el código Scanner se encarga de la NumberFormatException para usted y luego lanza un tipo diferente de excepción:

de java.util.Scanner:

public double nextDouble() { 
    // Check cached result 
    if ((typeCache != null) && (typeCache instanceof Double)) { 
     double val = ((Double)typeCache).doubleValue(); 
     useTypeCache(); 
     return val; 
    } 
    setRadix(10); 
    clearCaches(); 
    // Search for next float 
    try { 
     return Double.parseDouble(processFloatToken(next(floatPattern()))); 
    } catch (NumberFormatException nfe) { 
     position = matcher.start(); // don't skip bad token 
     throw new InputMismatchException(nfe.getMessage()); 
    } 
} 

Cuando te encuentras con un problema así, recomiendo que mires a través de la fuente Java como primera parada. Es un gran recurso.

También tenga en cuenta que no hay ScannerException en el JDK.

+0

gracias. ¡Fue realmente útil! – Tony

0

Simplemente tome InputMismatchException en lugar de NumberFormatException y todo funciona bien.

+0

¿funciona bien cuando escribe letras en lugar de números en las indicaciones de entrada? – akf

+0

Por supuesto que no. El código no capta la excepción correcta. – Thunderhashy

0

¿Por qué no hacer:

String input = scan.nextLine(); 
if(!input.matches("\\d+")) { // regex for 1 or more digits 
    System.err.println("Input must be at least 1 digit!"); 
    continue; // goes back to the top of the loop 
} 
double dbl = Double.valueOf(input); 

FYI, la expresión regular real de doble precisión sería [dígitos] [dígitos] con [dígitos] siendo opcional [.] [.].