所以我有一个非常大的java应用程序,我在一年前写过,我试图再次理解它。我正在查看代码中的一个方法,其中存在明显的获取NoSuchElementException的风险:我在一个用任意字符串构造的扫描器变量上调用.next()。声明抛出该方法的唯一方法是定制的Exception子类。危险命令也不是写在catch-block中。代码编译和工作正常,当我以这样的方式使用我的gui它应该抛出NoSuchElementException没有任何反应:O
作为测试,我在代码中编写了一个catch-block,编译它,运行gui并使它再次抛出NoSuchElementException,应用程序成功捕获异常并采取相应的行动。如何在不指定此异常的情况下编译代码可能会被抛出?如果它完全没用,这里是没有catch-block的代码:
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());
正如您所看到的,该方法只是假设在检查是否存在至少一个单词后,扫描仪中有多个单词。我怎么逃避编译呢?
答案 0 :(得分:7)
原因是NoSuchElementException
是未经检查的异常,这意味着它是“is-a”RuntimeException
,它不会强迫您捕获。
未经检查的异常类是RuntimeException类及其子类,以及类Error及其子类。所有其他异常类都是已检查的异常类。 Java API定义了许多异常类,包括已检查和未选中的异常类。程序员可以声明其他检查和未检查的异常类。有关异常类层次结构的描述以及Java API和Java虚拟机定义的一些异常类,请参阅ref。
Runtime exceptions
与检查异常的目的相同;向用户传达异常情况(意外故障等)。
checked异常强制方法的调用者处理该异常,即使他们不知道如何处理它。通常情况下,开发人员最终会捕获已检查的异常,只会重新抛出异常(或其他异常)。因此Runtime exceptions
这是异常层次结构
答案 1 :(得分: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());
}
答案 2 :(得分:0)
java.util.NoSuchElementException
是java.lang.RuntimeException
的子类。 RuntimeException
不需要处理。从Java API文档:
RuntimeException
是在Java虚拟机正常运行期间可以抛出的异常的超类。
RuntimeException
及其子类是未经检查的例外。未经检查的异常 not 需要在方法或构造函数的throws
子句中声明,如果它们可以通过执行方法或构造函数抛出并在方法或构造函数边界外传播。