6

是否可以仅通过查看代码来判断异常类是已选中还是未选中?我一直认为,如果它扩展了 Exception,它就被选中了,但是 RuntimeException 扩展了 Exception 并且没有被选中。RuntimeException 可能是唯一违反该经验法则的类,如果不扩展 RuntimeException,其他未经检查的异常必须扩展 Throwable。但是,我看不出 RuntimeException 与 Exception 有何不同。我想知道差异是否在解释器本身内部定义?

4

8 回答 8

4

RuntimeException它的子类是未经检查的异常。所有其他都是检查异常。

于 2014-03-14T12:57:33.960 回答
2

是否可以仅通过查看代码来判断异常类是已选中还是未选中?

是的。如果您知道 JLS ( 11.1.1 )中指定的规则...并且您还可以查看异常超类的代码(以便您可以检查层次结构)。

规则是“检查”例外情况,但以下情况除外

  • RuntimeException及其子类,以及

  • Error及其子类,

这是“未经检查的”。

我想知道差异是否在解释器本身内部定义?

不,它在 Java 语言规范中。事实上,JVM 对已检查和未检查异常的处理是一样的。所有检查检查的异常是否被正确处理的检查都是由 Java 编译器完成的。


但是,我仍然不明白 RuntimeException 扩展 Exception 而不是 Throwable 的原因。考虑到 RuntimeException 中没有任何内容可以覆盖 Exception 中定义的行为,这种设计选择似乎是矛盾的。

它就是这样。此外,我没有看到任何逻辑上的矛盾。

  • AnError表示不可恢复的状态。未选中它是因为没有必要强制应用程序对其执行某些操作。

  • AnException代表一种潜在的可恢复状态。

  • ARuntimeException表示我们不想强制应用程序处理的潜在可恢复条件。(但它可以,如果它愿意的话)。

显然,根据这种分类法,a RuntimeException>>is<< anException和 >>not<< an Error... 这就是以这种方式定义异常类层次结构的基本原理。

于 2014-03-14T13:16:48.667 回答
2

您可以在Java 教程(强调我的) 中找到未检查异常的定义:

... Java 编程语言不需要方法来捕获或指定未经检查的异常(RuntimeException、Error 及其子类) ...

于 2014-03-14T12:58:37.170 回答
1

而不是“捕获与未捕获”,它们被称为“已检查与未检查”异常。在编译时检查的异常是受控的,即编译器会在某些不符合异常合同的情况下向您发出警告,但可以在运行时抛出未经检查的异常。

于 2014-03-14T12:58:24.837 回答
0

如果您使用 IDE 是最简单的方法,如果您的 IDE 给您一个错误/下划线,告诉您当您没有捕获它时您有一个未处理的异常。那些是检查异常。

或者,从 RuntimeException 继承的任何内容都未选中。

于 2014-03-14T12:59:33.430 回答
0

如果您使用任何throws exception明确的方法或代码,则需要捕获该异常,并且通过查看代码,我们确定我们需要捕获,因此已检查Exception。如果RuntimeException通过查看代码,您无法确保此代码会引发异常,因此它们未被选中。

Java 文档参考

方法可以抛出的任何异常都是该方法的公共编程接口的一部分。调用方法的人必须知道方法可以抛出的异常,以便他们可以决定如何处理它们。这些异常与其参数和返回值一样,都是该方法编程接口的一部分。

于 2014-03-14T13:06:26.810 回答
0

继承树Throwable实际上是:

可抛出错误
              异常运行时异常

抛出任何延伸ErrorRuntimeException不需要声明的地方。错误通常只由 JVM 抛出,并表示发生了非常糟糕的事情。

任何扩展Exception但不扩展的东西RuntimeException都需要声明。通常Exceptions是调用代码应该处理或考虑的事情(例如“无法打开文件”),而RuntimeExceptions可能表明代码中存在错误或数据损坏的事情,NullPointerException因此调用代码不太可能做关于它的任何事情。

于 2014-03-14T13:03:16.780 回答
0

正如javadoc所说:

RuntimeException 是可以在 Java 虚拟机正常运行期间抛出的那些异常的超类。方法不需要在其 throws 子句中声明任何可能在方法执行期间抛出但未被捕获的 RuntimeException 子类。

作者:弗兰克·耶林

自:JDK1.0

现在,回到您的问题,I wonder if the difference is defined inside the interpreter itself?....魔术是在bytecode中完成的。

下面的文章通过分析字节码来展示它:

http://www.javaworld.com/article/2076868/learn-java/how-the-java-virtual-machine-handles-exceptions.html

基本机制是 异常表

Exception table:
   from   to  target type
     0     4     4   <Class java.lang.ArithmeticException>

如果在方法执行期间抛出异常,Java 虚拟机将在异常表中搜索匹配条目。

如果当前程序计数器在条目指定的范围内,并且抛出的异常类是条目指定的异常类(或者是指定异常类的子类),则异常表条目匹配。

Java 虚拟机按照条目在表中出现的顺序搜索异常表。当找到第一个匹配项时,Java 虚拟机将程序计数器设置为新的 pc 偏移位置并继续在那里执行。

如果未找到匹配项,Java 虚拟机将弹出当前堆栈帧并重新引发相同的异常。

当 Java 虚拟机弹出当前堆栈帧时,它有效地中止当前方法的执行并返回到调用此方法的方法。但不是在前一个方法中继续正常执行,而是在该方法中抛出相同的异常,这导致 Java 虚拟机通过相同的过程搜索该方法的异常表。

于 2014-03-14T13:16:21.547 回答