我正在编写一个读取文件的Java程序。该程序至关重要地依赖于这个文件,所以我真的希望程序在读取文件时因为某种原因而结束。
结束该计划的最佳方式是什么?我想我被迫在try / catch块中包围我的文件读取,所以我应该在我的catch中添加System.exit(0)
吗?例如,我应该做以下的事情吗?
try {
BufferedReader br = new BufferedReader(new FileReader("myfile.txt"));
String line;
while ((line = br.readLine()) != null) {
// process...
}
} catch(IOException e) {
System.out.println("Error: " + e);
System.exit(0); // ???
}
答案 0 :(得分:35)
如果让异常一直传播到main()
方法,程序将结束。无需调用System.exit
,只需允许异常自然地将堆栈冒泡(通过添加throws IOException
)到必要的方法。
编辑:正如@Brian指出的那样,您可能希望捕获IOException
方法中的main
,并在其中调用System.exit
,提供人类可读的错误消息(堆栈)痕迹可以吓唬人)。另外,正如@MeBigFatGuy所说,从代码堆栈中调用System.exit
是不好的做法,并限制了代码的可重用性。如果您必须使用System.exit
,请将其保留在main
方法的正文中。
答案 1 :(得分:8)
没关系。但是0
作为退出代码意味着程序按预期结束。你会想要使用不同的数字;)
答案 2 :(得分:8)
如果你真的希望立即终止程序,而不是让程序的上层决定做什么(可能某天你的程序核心会延长,以便从myfile.txt
中选择一个来源各种网站,或语音合成或直接脑转移),你应该调用:System.exit(1)
(或其他一些非零退出状态)。
退出代码0
向shell(和父进程)说明执行正常完成。非零退出代码报告存在错误。这对于制作出色的工具来通知管理员异常执行错误或编写友好的小程序至关重要:
./fiddle_with_words myfile.txt || mail -s "program failed" grautur@example.com
答案 3 :(得分:4)
@gratur在@skaffman的回答中发表评论。
因此,如果我理解正确,我通过删除try / catch块并向该方法添加“throws IOException”(以及调用该方法的方法等)来让异常冒泡?我觉得有点蠢,因为现在我必须添加一堆“抛出IOException”到处 - 我的ickiness被误导了吗?
我认为这取决于。如果异常只需要冒出少量级别,并且传播IOException
的方法是有意义的,那么这就是你应该做的。关于允许异常传播没有什么特别“icky”。
另一方面,如果IOException
必须传播到多个级别并且没有机会它可能会被特定地处理超过某一点,您可能希望:< / p>
ApplicationErrorException
,它是RuntimeException
,IOException
靠近其来源并在其位置投放ApplicationErrorException
...当然使用cause
套,ApplicationErrorException
方法中捕获main
例外。在main
中您抓住ApplicationErrorException
的位置,您可以使用非零状态代码调用System.exit()
,并可选择打印或记录堆栈跟踪。 (事实上,您可能希望通过专门化“应用程序错误”异常来区分您执行和不希望堆栈跟踪的情况。)
请注意,我们仍然允许异常传播到main
...出于@ skaffman的回答中解释的原因。
使这个问题复杂化的最后一件事是在main
线程以外的某个线程的堆栈上抛出的异常。您可能不希望异常被处理并在另一个线程的堆栈上变成System.exit()
...因为这不会让其他线程有机会干净地关闭。另一方面,如果您不执行任何操作,则默认行为是另一个线程仅以未捕获的异常终止。如果没有任何内容join()
- 线程,这可能会被忽视。不幸的是,没有简单的“一刀切”的解决方案。