如何捕获 NoSuchElementException?

Eri*_*a E 5 java exception-handling

我的课堂作业是编写一个程序,让用户输入一组数值。如果用户输入的值不是数字,程序应该给用户 2 秒的机会正确输入一个数字,在这两次机会之后,停止要求输入并打印到目前为止正确输入的所有值的总和.

照原样,我的代码不能正常工作。当输入第一个非数字时,程序执行一次 catch 块中的代码,在 try 块的开头打印“gimme input”行,然后立即再次执行 catch 块中的代码,无需等待用户输入另一个号码。

在仔细阅读我的教科书以寻找线索时,我注意到这一行:“任何 catch 子句都不会捕获NoSuchElementException 。异常一直抛出,直到它被另一个 try 块捕获或 main 方法终止。”

这很好,因为现在至少我知道发生这种情况是有充分理由的,但是我的教科书没有包含有关此怪癖的任何进一步信息,而且我无法通过 StackOverflow 或 Google 找到任何可以理解的答案。所以我的问题是两部分:

a) 为了这个任务的目的,我应该如何解决这个问题?

b) 异常没有被 catch 子句捕获到底是什么意思?那不是catch 子句存在的目的吗?我确实想要我的任务的解决方案,但我也想了解为什么会这样,如果可能的话。

谢谢你的帮助!

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.");
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

Tof*_*eer 4

现在,忘记捕获异常(这不是您想要做的!)。你想要做的是在调用 s.nextDouble() 之前添加如下调用: s.hasDouble() 。

您不想捕获该异常的原因是因为它是一个 RuntimeException,旨在用于指示程序员的错误,您应该修复该错误。

简单的建议是不要捕获编译器没有告诉您要捕获的异常,相反,如果抛出其中一个异常,请找出需要对代码进行的更改,以便不会发生异常。

对于异常,编译器会告诉您必须处理它们,您可以执行以下操作:

try
{
    foo();
}
catch(final IOException ex)
{
    // do something smarter here!
    ex.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

在该代码中,foo() 的声明如下:

public void foo() 
    throws IOException 
{
   // ... code ...
}
Run Code Online (Sandbox Code Playgroud)

IOException 是一个检查异常(RuntimeException,也称为非检查异常,不应该被捕获,检查异常必须被捕获......除了捕获之外,你还可以做其他事情,但现在不用担心这些)。

s.hasXXX()因此,长答案短,通过在调用之前调用来使异常不会发生s.nextXXX()