web-dev-qa-db-fra.com

Essayez/attrapez en Java

Quelqu'un pourrait-il me dire, s'il vous plaît, pourquoi cet essai et interception ne fonctionne pas? Il génère une exception scanner au lieu d'imprimer le message que j'attends.

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;
    }
}
8
Tony

Simple, le programme lève ScannerException, mais votre catch try ne peut attraper que NumberFormatException, vous devez ajouter une autre clause catch pour attraper ScannerException ou ne capturer que l'Exception générique.

par exemple, quand vous dites:

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

c'est seulement spécifier comment attraper NumberFormatException.
Pour intercepter toutes les exceptions, vous devez le faire:

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

Dans ce cas, la deuxième capture obtiendrait tout ce qui n'était pas capturé dans la première, car toutes les exceptions étendent la classe Exception, vous pouvez intercepter toutes les classes dérivées avec cette instruction.

Cependant, puisque saisir Exception en soi est mal vu, vous pouvez également faire:

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

Pour attraper les deux exceptions dans le même bloc.

21
zmbush

Vous essayez d'attraper une exception NumberFormatException. Vous devez ajouter une instruction catch pour une ScannerException, car elle est différente de NumberFormatException.

4
Jeff

Vous devez attraper une ScannerException ou une telle chose.

À ce code, vous attrapez seulement le NumberFormatException

Essayez-en comme ça:

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

Vous attrapez la mauvaise exception.

1
Anon.

Votre code ne jettera pas une NumberFormatException. Vous devriez plutôt attraper une InputMismatchException

En regardant nextDouble, dans Scanner, il semble que le code Scanner gère la NumberFormatException pour vous puis lève un type d'exception différent: 

à partir 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());
    }
} 

Lorsque vous rencontrez un problème comme celui-ci, je vous recommande de consulter d'abord le code source Java. C'est une excellente ressource.

Notez également qu'il n'y a pas de ScannerException dans le JDK.

0
akf

Attrapez simplement InputMismatchException au lieu de NumberFormatException et tout fonctionne bien.

0
Thunderhashy

Pourquoi ne pas simplement faire:

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);

Pour votre information, l'expression régulière de la double précision serait [chiffre] [.] [Chiffre], le [.] [Chiffre] étant facultatif.

0
Droo