Java NoTouchElementException

Java NoTouchElementException,java,exception,exception-handling,nosuchelementexception,Java,Exception,Exception Handling,Nosuchelementexception,所以我有一个相当大的java应用程序,我在一年前写的,我正试图再次理解它。我正在查看代码中的一个方法,其中存在获取NoTouchElementException的明显风险:我正在对使用任意字符串构造的scanner变量调用.next()。该方法声明抛出的唯一对象是定制的Exception子类。危险的命令也不会写在catch块中。代码编译并运行良好,当我以这样的方式使用gui时,它应该抛出一个NosTouchElementException,什么也不会发生:O 作为测试,我在代码中编写了一个cat

所以我有一个相当大的java应用程序,我在一年前写的,我正试图再次理解它。我正在查看代码中的一个方法,其中存在获取NoTouchElementException的明显风险:我正在对使用任意字符串构造的scanner变量调用.next()。该方法声明抛出的唯一对象是定制的Exception子类。危险的命令也不会写在catch块中。代码编译并运行良好,当我以这样的方式使用gui时,它应该抛出一个NosTouchElementException,什么也不会发生: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());

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

这是因为
NoTouchElementException
是未检查的异常,这意味着它“是一个”
RuntimeException
,不会强迫您捕获

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

运行时异常
与已检查异常的用途相同;向用户传达异常情况(意外故障等)

checked exception强制方法的调用方处理该异常,即使他们不知道如何处理该异常。通常情况下,开发人员最终会捕获已检查的异常,然后重新抛出它(或另一个异常)。因此,
运行时异常

下面是异常层次结构


java.util.NoSuchElementException
java.lang.RuntimeException
的子类<代码>运行时异常s不需要处理。从Java API文档中:

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

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


由于问题已经得到了回答,我想指出这是一个非常糟糕的设计,不是
扫描仪
类的预期用途:

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());
}

我不知道我在哪里声明该方法抛出它,Hunter,请详细说明。在我看来,如果(scanner.hasnetint()){return new Integer(scanner.nextInt();}执行与简单操作完全相同的操作:return new Integer(scanner.nextInt());关键是,只有当扫描程序中有一个整数准备就绪时,它才会这样做,如果没有,并且您没有检查,您将得到
NoTouchElementException
。是的,但显然该异常根本没有后果。那么得到它和什么也得不到之间的区别是什么呢?我看不出来重点是设计
RuntimeException
s表示您不应该尝试处理的严重问题,在这种情况下,这是因为您的代码不正确地使用了类:您应该先检查。