Java NoSuchElementException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18988765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:07:24  来源:igfitidea点击:

Java NoSuchElementException

javaexceptionexception-handlingnosuchelementexception

提问by user2651804

So I have a pretty big java application that I wrote a year ago and I'm trying to understand it again. I'm looking at a method in the code where there is an obvious risk of getting NoSuchElementException: I'm calling .next() on a scanner variable that has been constructed with an arbitrary string. The only thing the method is declared to throw are custom made subclasses of Exception. The risky command isn't written in a catch-block either. The code compiles and works fine and when I use my gui in such a fashion that it should throw a NoSuchElementException nothing happens :O

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

As a test I wrote a catch-block into the code, compiled it, ran the gui and made it throw NoSuchElementException again and the application successfully caught the exception and acted accordingly. How is it that I can compile the code without specifying the this exception may be thrown? If it's any use at all, here is the code without the catch-block:

作为测试,我在代码中编写了一个 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());

As you can see, the method simply assumes that there is more than one word in the scanner after checking if there is at least the one. How am I getting away with compiling this?

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

采纳答案by codeMan

It is be cause NoSuchElementExceptionis unchecked exception, which means that it "is-a" RuntimeExceptionwhich does not force you to catch.

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

The unchecked exceptions classes are the class RuntimeException and its subclasses, and the class Error and its subclasses. All other exception classes are checked exception classes. The Java API defines a number of exception classes, both checked and unchecked. Additional exception classes, both checked and unchecked, may be declared by programmers. See reffor a description of the exception class hierarchy and some of the exception classes defined by the Java API and Java virtual machine.

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

Runtime exceptionsserve the same purpose as checked exceptions; to communicate exceptional conditions (unexpected failures, etc) to the user.

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

checked exception forces the caller of a method to handle that exception, even if they do not know how to handle it. Often times, developers will end up catching the checked exception, only to re-throw it (or another exception). Hence the Runtime exceptions

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

Here is the exception hierarchy

这是异常层次结构

enter image description here

在此处输入图片说明

回答by PurkkaKoodari

java.util.NoSuchElementExceptionis a subclass of java.lang.RuntimeException. RuntimeExceptions don't have to be handled. From the Java API documentation:

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

RuntimeExceptionis the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine.

RuntimeExceptionand its subclasses are unchecked exceptions. Unchecked exceptions do notneed to be declared in a method or constructor's throwsclause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary.

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

RuntimeException它的子类是未经检查的异常。不要unchecked异常并不需要一个方法或构造方法中声明throws条款,如果他们可以通过该方法或构造边界之外的方法或构造和宣传的执行被抛出。

回答by MrLore

As the question has already been answered, I'd like to point on that this is very poor design and not the intended usage of the Scannerclass:

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

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

What you should really be doing is ask the scanner whether there is any input, and only then retrieving it, like so:

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

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

The same applies to the line which is causing your problem:

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

if(scanner.hasNextInt()) {
    return new Integer(scanner.nextInt());
}