12

ClassNotFoundException成为检查异常的原因是什么?

我一直在猜测和谷歌搜索试图理解为什么将找不到类视为已检查异常,因为我所有的想法都告诉我它应该不被检查。

4

3 回答 3

7

当接收者可以/应该采取一些有意义的行动来在运行时纠正问题时,通常会检查异常。

未经检查的例外——争议说:

这是底线准则:如果可以合理地期望客户端从异常中恢复,则将其设为已检查异常。如果客户端无法从异常中恢复,请将其设为未经检查的异常。

s最常见的来源ClassNotFoundException是类似的代码

classLoader.loadClass(className);

它基于在配置文件、序列化输入或远程过程调用中找到的名称反射性地加载一个类。

与之相反ClassNotFoundError,大多数情况下,程序是用其他类静态编译的,而 JVM 的链接器在运行时找不到这些类。

反射用例(已检查)与链接静态编译代码失败(运行时错误)有何区别?


语境

反射:调用者知道字符串的来源以及尝试加载的原因。

静态:调用者只是试图使用在编译时可用的类。没有可用的上下文。

恢复

反射:调用者可以故障转移到不同的实现或尝试默认策略。

静态:Java 语言不明确支持替换不同的链接点。

改写

反射:调用者应该经常将错误转换为不同的类型,例如
IOException序列化失败。

静态:如果您的程序的一部分丢失了,那么您不能依靠程序的必要部分来解释为什么一个部分缺少其他部分。

于 2013-05-11T14:17:47.110 回答
5

ClassNotFoundException当您的代码调用Class.forName()无法解析为应用程序类路径上的类的类名时,将抛出A (松散地说)。它可能是应用程序用户提供的拼写错误的类名,因此可能有理由将其报告给用户,甚至可能使用更正的类名重试。换句话说,这可以是一个可恢复的错误......在某些情况下......所以你可以争辩说检查它的决定是适当的。

无论哪种方式:

  • 检查与未检查之间的任何选择的“正确性”是一个问题,而不是客观事实,
  • 过去,Java 设计者在某些情况下做出了错误的选择,并且
  • 一旦做出选择,就没有回头路......不破坏向后兼容性。

相比之下,如果您在类加载/初始化过程中遇到问题,您很可能会得到一个NoClassDefFoundError. 这绝对是不可挽回的。当这种情况发生时,您的一个或多个类处于它们存在于 JVM 中但无法初始化或实例化的状态。(您还将看到NoClassDefFoundErrorJVM 是否无法找到您指定的入口点类。但如果发生这种情况,您的应用程序甚至没有机会尝试恢复......)

于 2013-05-11T14:13:48.830 回答
1

未经检查的异常用于您的程序无法恢复的错误。Checked Exceptions 适用于您可以从中恢复的无效条件。

据我所知,检查异常的概念只存在于 Java 中。

现在的问题是程序能否从 ClassNotFoundException 中恢复?

这大部分时间是由方法 Class.forName 抛出的。这取决于您的程序,因此检查和未检查的概念有点随机,因为 API 开发人员应该如何知道我的程序是否可以从中恢复。当我在运行时需要该类并且无法处理时,这对我来说是未选中的,但是当我向用户询问某些内容并基于此加载一个类时,可能输入是错误的,我可以向他询问其他内容。但大多数时候我会说你无法从中恢复过来,最好是不受约束的。

但是在我看来,API 和第三方使用已检查的异常来提醒程序员可能会发生此问题并需要考虑它。由于加载基于纯字符串的内容可能会失败并且与整个 Java 静态类型语言概念不兼容,因此异常被标记为已检查,因此提醒您破坏静态安全。然而,这只是我的意见。

最后由异常的开发者做出决定,他可能是错的或对的,或者可能像我一样考虑其他一些原因。

于 2013-05-11T14:22:02.737 回答