2

所以我有一年前写的一个相当大的java应用程序,我试图再次理解它。我正在查看代码中的一个方法,其中存在明显的 NoSuchElementException 风险:我正在使用任意字符串构造的扫描仪变量上调用 .next()。该方法声明要抛出的唯一东西是自定义的 Exception 子类。有风险的命令也没有写在 catch-block 中。代码编译并运行良好,当我以这样的方式使用我的 gui 时,它应该抛出 NoSuchElementException 没有任何反应:O

作为测试,我在代码中编写了一个 catch 块,编译它,运行 gui 并让它再次抛出 NoSuchElementException,应用程序成功地捕获了异常并采取了相应的行动。我如何编译代码而不指定可能引发的异常?如果它有任何用处,这里是没有 catch 块的代码:

public static Expression interpret(final Scanner scanner)
  throws
    InvalidPosition,
    NoSuchSpreadsheet,
    IllegalStartOfExpression,
    InvalidExpression,
    FalseSyntax,
    InvalidRange {

String keyword = null;

try {
  keyword = scanner.next();
} catch (NoSuchElementException e) {
  throw new IllegalStartOfExpression();
}

switch(keyword) {
  case "Get":
    Position pos = PositionInterpreter.interpret(scanner.next());
    Expression expression = Application.instance.get(pos);
    if (expression instanceof Text) {
        System.out.println("Failure");
    } else { System.out.println("Success"); }
    return new Text(expression.toString());
  case "Int":
    return new Int(
      scanner.nextInt());

如您所见,该方法只是在检查是否至少有一个单词后假设扫描仪中存在多个单词。我如何摆脱编译这个?

4

3 回答 3

7

原因NoSuchElementException 是未经检查的异常,这意味着它“是-a” RuntimeException不会强迫您捕获。

未经检查的异常类是类 RuntimeException 及其子类,以及类 Error 及其子类。所有其他异常类都是检查异常类。Java API 定义了许多异常类,包括选中的和未选中的。程序员可以声明额外的异常类,包括已检查和未检查的。有关异常类层次结构和 Java API 和 Java 虚拟机定义的一些异常类的描述,请参见参考文献。

Runtime exceptions与受检异常的目的相同;向用户传达异常情况(意外故障等)。

已检查异常强制方法的调用者处理该异常,即使他们不知道如何处理它。通常,开发人员最终会捕获已检查的异常,只是为了重新抛出它(或另一个异常)。因此Runtime exceptions

这是异常层次结构

在此处输入图像描述

于 2013-09-24T18:05:03.967 回答
2

由于问题已经得到解答,我想指出这是非常糟糕的设计,而不是Scanner该类的预期用途:

try {
  keyword = scanner.next();
} catch (NoSuchElementException e) {
  throw new IllegalStartOfExpression();
}

您真正应该做的是询问扫描仪是否有任何输入,然后才检索它,如下所示:

if(scanner.hasNext()) {
    keyword = scanner.next();
}
else {
   throw new IllegalStartOfExpression();
}

这同样适用于导致您的问题的行:

if(scanner.hasNextInt()) {
    return new Integer(scanner.nextInt());
}
于 2013-09-24T18:13:02.020 回答
0

java.util.NoSuchElementException是 的子类java.lang.RuntimeExceptionRuntimeExceptions 不必处理。来自 Java API 文档:

RuntimeException是在 Java 虚拟机正常运行期间可以抛出的那些异常的超类。

RuntimeException它的子类是未经检查的异常。如果未经检查的异常可以通过方法或构造函数的执行抛出并传播到方法或构造函数边界之外,则不需要在方法或构造函数的子句声明它们。throws

于 2013-09-24T18:07:26.130 回答