【发布时间】:2013-05-06 01:28:48
【问题描述】:
ClassNotFoundException 成为检查异常的原因是什么?
我一直在猜测和谷歌搜索,试图理解为什么将找不到类视为已检查异常,因为我的脑海里全都告诉我应该取消检查。
【问题讨论】:
标签: java exception classnotfoundexception
ClassNotFoundException 成为检查异常的原因是什么?
我一直在猜测和谷歌搜索,试图理解为什么将找不到类视为已检查异常,因为我的脑海里全都告诉我应该取消检查。
【问题讨论】:
标签: java exception classnotfoundexception
当接收方可以/应该采取一些有意义的行动来在运行时纠正问题时,通常会检查异常。
Unchecked Exceptions — The Controversy 说:
以下是底线准则:如果可以合理地期望客户端从异常中恢复,则将其设为已检查异常。如果客户端无法从异常中恢复,请将其设为未经检查的异常。
ClassNotFoundExceptions 最常见的来源是类似代码
classLoader.loadClass(className);
反射性根据配置文件、序列化输入或远程过程调用中的名称加载类。
这与ClassNotFoundError 形成对比,ClassNotFoundError 通常是由静态编译的程序与运行时 JVM 链接器无法找到的其他类一起编译的。
反射用例(检查)与链接静态编译代码失败(运行时错误)有何区别?
反射性:调用者知道字符串的来源以及尝试加载的原因。
静态:调用者只是试图使用在编译时可用的类。没有可用的上下文。
反射:调用者可以故障转移到不同的实现或尝试默认策略。
静态:Java 语言不明确支持替换不同的链接点。
反思:调用者应该经常将错误转换为不同的类型,例如IOException 反序列化失败。
静态: 如果您的程序缺少一部分,那么您不能依靠程序的必要部分来解释为什么其中一个部分缺少其他部分。
【讨论】:
当您的代码在无法解析为应用程序类路径上的类的类名上调用 Class.forName() 时,将抛出 ClassNotFoundException(松散地说)。它可能是应用程序用户提供的拼写错误的类名,因此可能有理由将其报告给用户,甚至可能使用更正的类名重试。换句话说,这可能是一个可恢复的错误......在某些情况下......所以你可以争辩说检查它的决定是适当的。
无论哪种方式:
相比之下,如果您在类加载/初始化过程中遇到问题,您很可能会收到NoClassDefFoundError。这绝对是不可挽回的。当这种情况发生时,您的一个或多个类处于它们存在于 JVM 中但无法初始化或实例化的状态。 (如果 JVM 找不到您指定的入口点类,您还会看到 NoClassDefFoundError。但如果发生这种情况,您的应用程序甚至没有机会尝试恢复......)
【讨论】:
SQLException。
未经检查的异常用于您的程序无法恢复的错误。 Checked Exceptions 适用于您可以从中恢复的无效条件。
据我所知,检查异常的概念只存在于 Java 中。
现在的问题是程序能否从 ClassNotFoundException 中恢复?
这大部分时间是由方法 Class.forName 抛出的。这取决于您的程序,因此检查和未检查的概念有点随机,因为 API 开发人员应该如何知道我的程序是否可以从中恢复。当我在运行时需要该类并且无法处理时,这对我来说是未经检查的,但是当我向用户询问某些内容并基于此加载一个类时,可能输入是错误的,我可以向他询问其他内容。但大多数时候我会说你无法从中恢复过来,最好是不受约束的。
但在我看来,api 和第三方使用已检查的异常来提醒程序员可能会出现此问题并需要考虑它。由于加载基于纯字符串的内容可能会失败并且与整个 Java 静态类型语言概念不兼容,因此异常被标记为已检查,因此提醒您破坏静态安全。不过这只是我的看法。
最终决定是由异常的开发者做出的,他可能是错的,也可能是对的,或者可能像我一样考虑其他一些原因。
【讨论】: