3

Let's say I have a piece of code that takes user input and stores it in integer. Now when user enters something else, the NumberFormat exception is thrown. But since I know this may happen, but there is no reason for me to do anything about it besides checking it and then re-run the input sequence, would it be terrible idea to put the try-catch inside do-while loop and making a boolean a control variable? Is there a case where such exception handling could backfire at me?

Pseudo-code:

Scanner scanner = new Scanner(System.in);
boolean inputMismatch;
int number;
do {
    try {
        System.out.println("Enter a number");
        number = Integer.parseInt(scanner.nextLine());
        inputMismatch = false;
    } catch (NumberFormatException e) {
        e.printStackTrace();
        inputMismatch = true;
    }

} while (inputMismatch);
Makoto
  • 104,088
  • 27
  • 192
  • 230
The Law
  • 344
  • 3
  • 20
  • 2
    No, that's a pretty common use case (for such applications). – Kayaman Oct 27 '15 at 19:56
  • 1
    Yup. Looks like a sound methodology to me. – Mad Physicist Oct 27 '15 at 19:57
  • If there's an easy way to check without cathcing an exception, use it (e.g. calling `file.exists()` to avoid `FileNotFoundExdception`). In your case however, there's no such way, so catching the exception is a reasonable thing to do. – Jiri Tousek Oct 27 '15 at 20:11
  • I would rather use `hasNextInt` and `next`/`nextLine` in case of an invalid input instead of catching an exception, but that's just my opinion. – Tom Oct 27 '15 at 20:33

4 Answers4

3

If you weren't going to include the catch in this block of code, it'd have to be one level up - namely, something would have to do this same loop and catch the exception. The only difference would be that it's encapsulated in a method which would throw the runtime exception.

This should be perfectly fine to do. You have to deal with the invalid input somewhere, and here looks fine.

Makoto
  • 104,088
  • 27
  • 192
  • 230
3

That's fine, but a little bit clumsy with the extra variable. I would do something like this:

Scanner scanner = new Scanner(System.in);
int number;
while(true) {
  try {
    System.out.println("Enter a number");
    number = Integer.parseInt(scanner.nextLine());
    break;
  } catch (NumberFormatException e) {
    System.err.println(e.getMessage());
  }
}

Now the control will break out of the while loop if the integer parses successfully, otherwise will print the error. Consider printing the message rather than the stack trace - users get confused by stack traces.

Tim Spears
  • 56
  • 3
  • +1 for not printing the stacktrace. i'd go further and say, because the exception is handled, there likely isn't any need to print in the catch. – djeikyb Oct 28 '15 at 05:44
2

Your logic and coding both look fine. This code will do exactly what you want with a minimum of side effects. You can also use a for or while loop to avoid having an uninitialized flag in the beginning. In the case of for loop, the flag will not even exist outside the loop:

Scanner scanner = new Scanner(System.in);
int number;
for(boolean inputMismatch = true; inputMismatch; ) {
    try {
        System.out.println("Enter a number");
        number = Integer.parseInt(scanner.nextLine());
        inputMismatch = false;
    } catch (NumberFormatException e) {
        e.printStackTrace();
    }
}

Note that you do not have to reset inputMismatch to true for every failed iteration of the loop if you do it before the loop.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
1

I think that's absolutely fine.

You could potentially encapsulate the parsing logic somewhere else so that the error handling is perhaps a little more explicit.

Here's a reference about the encapsulation:

Java: Good way to encapsulate Integer.parseInt()

Community
  • 1
  • 1
ryuu9187
  • 1,162
  • 7
  • 15