ClassNotFoundException
成为检查例外的原因是什么?
我一直在猜测和谷歌搜索试图理解为什么认为类未被发现为已检查异常,因为我的所有想法都告诉我它应该是未选中的。
答案 0 :(得分:7)
当接收者可以/应该采取一些有意义的行动来纠正运行时的问题时,通常会检查异常。
Unchecked Exceptions — The Controversy说:
以下是底线指南:如果可以合理地期望客户端从异常中恢复,请将其作为已检查的异常。如果客户端无法执行任何操作以从异常中恢复,请将其设置为未经检查的异常。
ClassNotFoundException
的最常见来源是类似
classLoader.loadClass(className);
反射根据配置文件,序列化输入或远程过程调用中的名称加载类。
这与ClassNotFoundError
形成对比,IOException
通常是由静态编译的程序产生的,其他类在运行时无法由JVM的链接器找到。
反射用例(已检查)与无法链接静态编译代码(运行时错误)的区别是什么?
反射:调用者知道字符串的来源以及尝试加载的原因。
静态:调用者只是尝试使用编译时可用的类。没有上下文。
反射:调用者可以故障转移到其他实现或尝试默认策略。
静态:Java语言没有明确支持替换不同的链接点。
反射:调用者应经常将错误转换为其他类型,例如
未能反序列化的{{1}}。
静态: 如果您的计划中缺少部分内容,那么您就不能依赖程序中必要的部分来解释为什么某个部分缺少其他部分。
答案 1 :(得分:5)
当您的代码在类名称上调用ClassNotFoundException
而无法解析为应用程序类路径上的类时,会抛出Class.forName()
(松散地说)。它可能是应用程序用户提供的拼写错误的类名,因此可能有理由向用户报告,甚至可能使用更正的类名重试。换句话说,这个可能是一个可恢复的错误......在某些情况下......所以你可以争辩说做出检查的决定是合适的。
无论哪种方式:
相比之下,如果在类加载/初始化过程中遇到问题,则可能会得到NoClassDefFoundError
。这绝对是不可恢复的。当发生这种情况时,您在JVM中存在一个或多个类,但无法初始化或实例化。 (如果JVM无法找到您指定的入口点类,您也会看到NoClassDefFoundError
。但如果发生这种情况,您的应用程序甚至不会有机会尝试恢复......)
答案 2 :(得分:1)
未经检查的例外用于您的程序无法恢复的错误。选中的例外情况适用于无法恢复的条件。
据我所知,已检查异常的概念仅存在于Java中。
现在问题是程序可以从ClassNotFoundException中恢复吗?
大部分时间都是通过Class.forName方法抛出的。这取决于你的程序,因此check和unchecked的概念有点随机,因为API开发人员应该知道我的程序是否可以从中恢复。当我在运行时需要该类并且无法处理时,这对我来说是未经检查的,但是当我向用户询问某些内容并根据此加载类时,输入可能是错误的,我可以向他询问其他内容。但大多数时候我会说你无法从中恢复过来,最好是不受控制。
但是在我看来,api和第三方使用了检查异常来提醒程序员这个问题可能发生并且需要考虑它。并且由于基于纯String加载某些内容可能会失败并且与整个Java静态类型语言概念不兼容,因此将异常标记为已检查,因此提醒您要破坏静态安全性。不过这只是我的意见。
最后,决定是由例外的开发者做出的,他可能是错的,也可能是正确的,或者可能会考虑其他一些原因。