views:

646

answers:

7
+3  Q: 

Try/catch in Java

Could someone please give me a hint why this try and catch is not working? It throws a scanner exception instead of printing the message I expect.

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;
    }
}
+1  A: 

You're catching the wrong exception.

Anon.
+3  A: 

You're attempting to catch a NumberFormatException. You need to add a catch statement for a ScannerException, as it is different from a NumberFormatException.

Jeff
There is no ScannerException in Java
Harsha
+1  A: 

You need to catch a ScannerException or some like this.

At this code you are only catching the NumberFormatException .

Try some like this:

    try {
       ...
    } catch (NumberFormatException, ScannerException exception) {
       JOptionPane.showMessageDialog(null,"Input must be a number.");
    }
Pedro Ghilardi
Forgive me if I am wrong, but shouldn't that be: `catch (NumberFormatException, ScannerException e) {`
zipcodeman
You are right. My mistake. =)
Pedro Ghilardi
how can we catch 2 exceptions in the same catch block?
Harsha
+12  A: 

Simple, the program throws ScannerException, but your try catch can only catch NumberFormatException, you need to add another catch clause in order to catch ScannerException, or catch only the generic Exception.

for example, when you say:

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

that is only specifying how to catch NumberFormatException.
In order to catch all exceptions, you would need to make it:

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

In this case, the second catch would get everything that was not caught in the first catch because all exceptions extend the Exception class, you can catch all derived classes with that statement.

However, since catching Exception by itself is frowned upon, you could also do:

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

To catch both exceptions in the same block.

zipcodeman
Although I would recommend catching the specific exception you want to catch - in this case a Scanner Exception - instead of a general exception catch. But This is correct.
aperkins
thank you. It was really helpful!
Tony
My personal favorite is catch(Throwable t)
Andres
Note that ScannerException does not exist in the JDK, and that NumberFormatException is also not thrown within that block.
akf
If you found a question to be helpful, it is good practice to accept the answer (I.E. select the checkmark on the answer you liked the best)
zipcodeman
A: 

Your code will not throw a NumberFormatException. You should catch an InputMismatchException instead.

Looking at nextDouble, in Scanner, it seems that the Scanner code handles the NumberFormatException for you and then throws a different type of exception:

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

When you hit a problem like this, I recommend that you look through the Java source as a first stop. It is a great resource.

Also note that there is no ScannerException in the JDK.

akf
thank you. It was really helpful!
Tony
A: 

Just catch InputMismatchException instead of NumberFormatException and everything works fine.

Harsha
does it work well when you type letters instead of numbers at the input prompts?
akf
Of course not.The code is not catching the right exception.
Harsha
A: 

Why not just do:

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, the actual regex for double precision would be [digit][.][digit] with the [.][digit] being optional.

Droo