简体   繁体   中英

Why does my try-catch when used to catch an error print out the error and my catch block?

I am currently learning about try-catch blocks of code and I am writing a piece of code that takes an input from a user and checks if its a integer or not. my code is

int classSize = 0;
boolean error = false;
    do {
        try{
            System.out.println("Hello! Please enter how many Students you have in your class: ");
            classSize = in.nextInt();
            error = false;
        }
        catch(InputMismatchException e){
            System.out.println("Invalid input. please make sure you enter numbers ONLY! No symbols or letters.");
            classSize = in.nextInt();
            error = true;
        }
    }while(error);

When I try to test it by entering letters I get both the error message and the try block message.

Hello! Please enter how many Students you have in your class: 
asdfsda

Invalid input. please make sure you enter numbers ONLY! No symbols or 
letters.

Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at ExcerciseOne.main(ExcerciseOne.java:65)

Why is it showing the catch block and the error message? Am I using the try-catch block properly?

You are catching the exception thrown in the try clause, but you are then reading from the scanner inside the catch again and thus throwing another exception, this time uncaught.

classSize = in.nextInt();

exists in both clauses, throwing an exception both times, but only gets caught when thrown from inside the try clause.

The in.nextInt() invocation inside the catch block reads the bad stream left behind by the first invocation of in.nextInt() in the try block.

What you can do is to remove the .nextInt() calls in the catch block:

boolean hasError = true;
while (hasError) {
    try {
        System.out.println("Hello! Please enter how many Students you have in your class: ");
        classSize = in.nextInt();
        hasError = false;
    } catch (InputMismatchException e) {
        System.out.println("Invalid input. please make sure you enter numbers ONLY! No symbols or letters.");
        // variable has error remains true
    }
}

Or better:

Since InputMismatchException is a subclass of RuntimeException , the kind of error that throws this error can be filtered out by if statements. Since you only need a proper integer as an input, you can validate the input using a regular expression.

boolean hasError = true;
String integerRegex = "[\\d]+"; // it means 1-to-many digits
while (hasError) {
    System.out.println("Hello! Please enter how many Students you have in your class: ");
    String input = in.nextLine();
    if (input.matches(integerRegex)) {
        classSize = Integer.parseInt(input);
        hasError = false;
    } else {
        System.out.println("Invalid input. please make sure you enter numbers ONLY! No symbols or letters.");
        // variable hasError remains true
    }
}

Gendarme's answer is clear, and I add a correct demo for you:

  public static void main(String[] args) {
      int studentsCount = 0;
      boolean hasError;
      do {
        try {
          System.out.println("Hello! Please enter how many Students you have in your class: ");
          Scanner in = new Scanner(System.in);
          studentsCount = in.nextInt();
          hasError = false;
        } catch (InputMismatchException e) {
          System.out.println("--> Invalid input. please make sure you enter numbers ONLY! No symbols or letters.");
          hasError = true;
        }
      } while (hasError);
      System.out.println("There are " + studentsCount + " students in your class.");
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM