简体   繁体   中英

java.lang.StackOverflowError on recursive function call

I wrote a program that accepts numbers from the user, and if the user entered, for example, a string instead of a number, then I recursively call the function for the user to enter a number, but in my example, the program throws a StackOverflowException error. If you know what the problem is, please write.

Code:

private static void inputMethod() {
    try {
        System.err.print("Enter a range from ");
        c = input.nextInt();
        System.err.print("Enter a range to ");
        d = input.nextInt();

        if(c > d) {
            System.err.println("Invalid Range Entry");
            inputMethod();
            return;
        }
        System.err.print("Enter the sum of digits ");
        q = input.nextInt();

        findNaturalNumbers();
    } catch(InputMismatchException e) {
        inputMethod();
    }
}

The problem is that when InputMismatchExcpetion is thrown, the garbage input that caused the error is still waiting to be read again by the next scanner call. That's so you could potentially go back and try to read it again with next() or nextLine() .

The cure is to "flush the toilet", so to speak, by calling either next() or nextLine() in your InputMismatchException handler:

boolean inputWasGood = false;
while (!inputWasGood){
    try {
        System.out.println("Enter a number: ");
        c = input.nextInt();
        inputWasGood = true;
    } catch (InputMismatchException ex) {
        input.nextLine();   // FLUSH AWAY THE GARBAGE!!
        System.out.println("Please don't enter garbage!");
    }
}
// FINALLY! We got some good input...

If you enter a letter instead of a number the input.nextInt() method throws an exception, but the cursor position in the input stream scanner is not advanced, it's still pointing to the letter. In the exception handler you call inputMethod() again, and because the cursor position is the same the input.nextInt() will again throw an exception, which will cause another call of inputMethod() and so on until the stack is blown up. What you should do is to use a hasNextInt() method to check if the next token on the stream is a correctly formatted integer and if so - read it with nextInt() . To simplify the process you can try to create an additional method which will prompt the user and ask for the input until the correct input is provided:

private int readInt(Scanner scanner, String prompt) {
  while (true) {
    System.out.println(prompt);
    if (scanner.hasNextInt()) {
      return scanner.nextInt();
    }
    System.out.println("Incorrect format of an integer number");
    scanner.nextLine();
  }
}

and then you can use it like this:

do {
  c = readInt(input, "Enter a range from ");
  d = readInt(input, "Enter a range to ");
  if(c > d) {
     System.err.println("Invalid Range Entry");
  }
} while (c > d);

q = readInt(input, "Enter the sum of digits ");
findNaturalNumbers();

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