Darnoc Eloc
Darnoc Eloc

Reputation: 105

Custom Exception Try Throw Catch in Java

I'm always getting the default NumberFormatException message when the variables d1 and d2 are not of the proper data type.

I want to print my custom Exception message when those exceptions are caught using the throw statement conditionals.

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    System.out.print("Enter a numeric value: ");
    String input1 = sc.nextLine();
    Double d1 = Double.parseDouble(input1);
    System.out.print("Enter a numeric value: ");
    String input2 = sc.nextLine();
    Double d2 = Double.parseDouble(input2);
    System.out.print("Choose an operation (+ - * /): ");
    String input3 = sc.nextLine();
    try {
        if (!(d1 instanceof Double)) {
            throw (new Exception("Number formatting exception caused by: "+d1));
        }
        if (!(d2 instanceof Double)) {
            throw (new NumberFormatException("Number formatting exception caused by: "+d2));
        }
        switch (input3) {
            case "+":
                Double result = d1 + d2;
                System.out.println("The answer is " + result);
                break;
            case "-":
                Double result1 = d1 - d2;
                System.out.println("The answer is " + result1);
                break;
            case "*":
                Double result2 = d1 * d2;
                System.out.println("The answer is " + result2);
                break; 
            case "/":
                Double result3 = d1 / d2;
                System.out.println("The answer is " + result3);
                break;
            default:
                System.out.println("Unrecognized Operation!");
                break;
        }
    }
    catch (Exception e){ 
        System.out.println(e.getMessage());
    }

}

}

This is an example of the message printed when entered value is not of proper format.

Enter a numeric value: $ Exception in thread "main" java.lang.NumberFormatException: For input string: "$" at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054) at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110) at java.base/java.lang.Double.parseDouble(Double.java:543) at com.example.java.Main.main(Main.java:13)

Upvotes: 0

Views: 1149

Answers (1)

Ordous
Ordous

Reputation: 3884

The problem with your code is that you make the check well after you've already attempted to parse it.

Your main clue is the stack trace that you get. It clearly shows that the exception is thrown at parseDouble on line 13. This is well before you do your own check, and the program never reaches it.

Your next step should then be checking the Javadoc of Double.parseDouble to see what it returns and when it throws.

The docs read (I've left out some things irrelevant to the question):

Returns a new double initialized to the value represented by the specified String

Throws:
    NullPointerException - if the string is null
    NumberFormatException - if the string does not contain a parsable double.

What this means, is that if you use this method to parse your doubles, then it will throw on invalid input.

What you do next depends on what your goal is. The 2 main problems with throwing exceptions are:
- You want your custom exception, rather than the default
- You want to avoid extra exceptions (so as not to generate stack trace, etc)

If you're in the first category, then the solution is simple - put the parseDouble into a try block and rethrow a custom exception if it fails, like this:

double d1;
try {
    d1 = Double.parseDouble(input1);
catch (NumberFormatException | NullPointerException e) {
    throw new MyCustomException("Please enter a valid double!", e);
}

If you do this, then you don't need to check again in your try/switch blocks (You've already guaranteed the input is a valid type!)

If you want to avoid the NumberFormatException entirely, then your best bet is to follow the advice on the Javadoc and use a rege to precheck the string before attempting to parse.

Upvotes: 6

Related Questions