How to catch NoSuchElementException?

how to catch a NoSuchElementException?

  • My class assignment is to write a program that has the user input a set of numerical values. If the user enters a value that is not a number, the program is supposed to give the user 2 second chances to enter a number correctly, and after those two chances, quit asking for input and print the sum of all values entered correctly so far. As is, my code doesn't work quite right. When the first non-number is entered, the program executes the code in the catch block once, prints the "gimme input" line at the beginning of the try block but then immediately executes the code in the catch block again without waiting for the user to enter another number. While perusing my textbook for clues, I noticed this line: "A NoSuchElementException is not caught by any of the catch clauses. The exception remains thrown until it is caught by another try block or the main method terminates." Which is great, because now at least I know there's a good reason this is happening, but my textbook doesn't contain any further information on this quirk, and I haven't been able to find any understandable answers via StackOverflow or Google. So my question is two part: a) How should I get around this for the purposes of this assignment? b) What exactly does it mean that the exception is not caught by a catch clause? Isn't that what catch clauses exist for? I do want a solution to my assignment, but I also want to understand why this is the way it is, if possible. Thanks for any help! import java.util.InputMismatchException; import java.util.NoSuchElementException; import java.util.ArrayList; import java.util.Scanner; public class NotANumber { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("This program computes the sum of any number of real numbers. When you are done entering values, enter something other than a real number twice in a row.\n"); ArrayList<Double> numbers = new ArrayList<Double>(); int count = 0; while (count < 2) { try { System.out.println("Please enter a floating point number: "); double newNumber = in.nextDouble(); numbers.add(newNumber); count = 0; } catch (NoSuchElementException exception) { System.out.println("The value entered was not correctly specified. All values must be integers or floating point values."); count++; } } if (!numbers.isEmpty()) { double sum = 0; for (Double each : numbers) { sum = sum + each; } System.out.println("The sum is " + sum); } else { System.out.println("There is no sum as no correctly specified values were entered."); } } }

  • Answer:

    For now, forget about catching the exception (it isn't what you want to do!). What you want to do is add calls like: s.hasDouble() before calling s.nextDouble(). The reason you don't want to catch that exception is because it is a RuntimeException which is meant to be used to indicate a programmer mistake, one that you should fix. The simple advice is don't catch exceptions that the compiler doesn't tell you to catch, instead if one of them is thrown figure out the change you need to make to your code so that exception doesn't happen. For exceptions the compiler tells you that you must deal with them you do something like: try { foo(); } catch(final IOException ex) { // do something smarter here! ex.printStackTrace(); } In that code, foo() is declared something like: public void foo() throws IOException { // ... code ... } IOException is a checked exception (RuntimeException, also called unchecked exceptions, should not be caught, checked exceptions must be caught... well you can do other things beyond catch, but for now don't worry about those). So, long answer short, make the exception not happen by calling s.hasXXX() before calling s.nextXXX().

Erika E at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

You are mistaken: Scanner.nextDouble throws a NoSuchElementException if the input is exhausted, which is unlikely to happen with standard input (it will block instead). An incorrect value will produce an InputMismatchException. My guess, however, is that nextDouble does not remove the offending value from the stream on failure. You'll need to "clear" the input in your catch before resuming the read.

Etienne de Martel

@TofuBear states: The simple advice is don't catch exceptions that the compiler doesn't tell you to catch, instead if one of them is thrown figure out the change you need to make to your code so that exception doesn't happen. I think that's an over-simplification. It is true that exceptions that are declared as checked exceptions HAVE to be either caught or declared as thrown in the method signature. It is also true that you don't have to catch unchecked exceptions, and indeed that you should think carefully about whether it wise to catch an unchecked. (For instance, you should think whether the exception is being thrown at the point you expect and for the reasons that you expect.) However, in some circumstances it is clearly necessary to catch them. For instance: try { System.out.println("Enter a lucky number!"); String input = // get string from user int number = Integer.parseInt(input); ... } catch (NumberFormatException ex) { System.err.println("Bad luck! You entered an invalid number"); } If you didn't catch NumberFormatException ... which is an unchecked exception ... then you wouldn't be in position to print out a friendly message, and ask the user to try again. In short, unchecked exceptions don't always mean programmer error. A few of the standard ones could indicate bad input from a user or client (e.g. NumberFormatException, IllegalArgumentException, ArithmeticException, etc), or they could indicate something that a specific application can recover from, or at least attempt to diagnose. I've come across third party libraries where the designer has an aversion to checked exceptions and has declared all library exceptions as unchecked. (Bad design IMO, but it happens ...) So a blanket statement that you shouldn't catch unchecked exceptions is clearly wrong advice. However the second part of @TofuBear's advice is valid. It is (generally) a better idea to do a test to prevent an anticipated exception from happening than to do the action and catch the exception. (The code is typically simpler, and typically more efficient ... though there are counter examples.) In this case, if you call and test hasNextDouble() before nextDouble() you can avoid the error case you are trying to handle with the try / catch.

Stephen C

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.