【发布时间】:2021-02-19 15:20:36
【问题描述】:
我知道这是一个非常菜鸟的问题。
我一直在浏览博客和文章,试图了解 Java 中使用错误的原因和位置,但没有运气。在实践中,我从未见过错误被使用,并且在异常情况下会发生错误。
这些只是供内部库使用吗?可以在程序中手动抛出吗?可能,我们不应该这样做,但我们可以吗?
【问题讨论】:
标签: java exception error-handling
我知道这是一个非常菜鸟的问题。
我一直在浏览博客和文章,试图了解 Java 中使用错误的原因和位置,但没有运气。在实践中,我从未见过错误被使用,并且在异常情况下会发生错误。
这些只是供内部库使用吗?可以在程序中手动抛出吗?可能,我们不应该这样做,但我们可以吗?
【问题讨论】:
标签: java exception error-handling
如果你愿意,可以扔掉它们。这是合法的 java 代码并且运行良好:
class Example {
public static void main(String[] args) {
throw new Error();
}
}
就像运行时异常一样,你不需要声明你这样做(假设你写了throw new IOException();,那么除非你把它变成…main(String[] args) throws IOException,否则它不会编译。运行时异常和错误不需要明确列出,但是。
有一个 ton 的代码可以捕获所有异常。这些通常是“入口点控制器”——启动应用程序的东西。 Java 本身会启动您的 main(并将捕获任何 main 抛出的内容,并将其转换为命令行上的漂亮打印),但 Web 服务器、应用程序服务器和插件运行器都做类似的事情:Web 服务器将接收 HTTP 请求,如图找出应该调用哪个处理程序代码来处理它,(有人编写了 Web 框架 - 但您编写了该处理程序),然后将捕获该处理程序之外的任何和所有异常,然后提供 500 错误并记录有关此事件的大量信息。您的public void doGet() 或您在 Web 处理程序中必须使用的东西是一个 入口点,而网络框架调用它的点称为 入口点控制器。 p>
大多数入口点控制器都有一个合法的:
try {
invokeEntryPoint();
} catch (Exception e) {
// deal with it...
// web frameworks would log the request, for example.
}
许多控制器不捕获错误,这是运行时异常和错误之间的实际主要区别:RuntimeExceptions 和 Errors 不需要在 throws 子句中说明,但 RuntimeExceptions 是常规的捕获,尤其是被入口点控制器捕获,而错误通常不会,因此它们会导致更彻底的堆栈展开:它“关闭”到进程的更深处。使用网络服务器,它可能会关闭整个网络服务器。这可能是一个好主意,例如,如果由于 VM 的磁盘损坏或系统内存不足而破坏了 JVM 不变量,那么这可能是比仅捕获错误、日志记录更好的选择(日志记录本身可以然后由于内存问题而不可能),然后继续。让操作系统看门狗自动重启服务器。
这就是务实的区别。
那么,你应该什么时候抛出Error?很少见,但如果您检测到违反有关您的应用程序的基本假设,即错误或配置错误(相对于正常操作期间可能发生的事件,例如用户上传的图像文件),这是有保证的这是无效的)。这种情况的常见情况是,如果您使用YourClass.class.getResource("states.txt") 来检索一些数据文件,这些数据文件与您的类文件一样多是您应用程序的一部分:如果丢失,那么您的安装已损坏,并且Error 很有道理:
try (InputStream in = AbichandanisApp.class.getResource("splash_screen.png")) {
if (in == null) throw new Error("Resource missing: splash_screen.png");
renderSplashScreen(new Image(in));
}
这是正确使用 throwing Error 的示例。
【讨论】:
当然可以(构造函数是公开的)。
如果您的代码中出现“合理的应用程序不应尝试捕获的严重问题”,您应该这样做。
见: https://docs.oracle.com/javase/7/docs/api/java/lang/Error.html
【讨论】:
SystemHasBeenTamperedWithError。