由于各种原因,在编写 Java应用程序时,调用System.exit
是不受欢迎的,那么如何通知调用进程并非所有内容都按计划进行?
修改:对于任何非零退出代码,1都是standin
。
答案 0 :(得分:25)
当'application'实际上是更大的Java应用程序(服务器)的子应用程序(例如servlet,applet)时,System.exit
的使用不受欢迎:在这种情况下,System.exit
可以停止JVM,因此也停止所有其他子应用程序。在这种情况下,抛出适当的异常(可以由应用程序框架/服务器捕获和处理)是最佳选择。
如果java应用程序真的要作为独立应用程序运行,那么使用System.exit
并没有错。在这种情况下,设置退出值可能是向父进程传达失败或成功的最简单(也是最常用)的方式。
答案 1 :(得分:8)
我同意“抛出异常”人群。一个原因是,如果您希望其他代码能够使用它,则调用System.exit会使您的代码难以使用。例如,如果您发现您的类在Web应用程序或某种消息消费应用程序中很有用,那么允许这些容器以某种方式处理故障将会很有用。容器可能想要重试操作,决定记录并忽略问题,向管理员发送电子邮件等。
例外情况是您的main()
方法;这可以捕获异常,并使用调用进程或shell脚本可以识别的某个值调用System.exit()
。
答案 2 :(得分:3)
System.exit()
将阻塞,并在启动它的线程用于关闭钩子时创建死锁。
答案 3 :(得分:1)
对正常退出感到不满意。如果“并非一切按计划进行”,那么System.exit就可以了。
更新:我应该补充一点,我认为你的'1'具有在某处记录的含义。
答案 4 :(得分:1)
在Web servlet环境中也存在危险/问题。
抛出异常通常被认为是另一种选择。
答案 5 :(得分:1)
我们公司的政策是调用System.exit(-1)是可以的(甚至是首选),但只能在init()方法中调用。在程序正常流程中调用它之前,我肯定会三思而后行。
答案 6 :(得分:1)
抛出异常是向上和向外发送有关某个错误的信息的最佳方式。
一个数字并没有告诉你:
Exception at thread 'main': FileNotFoundException "The file 'foo' doesn't exist"
(或接近那个)
答案 7 :(得分:1)
我认为抛出异常是出现问题时应该做的事情。这样,如果您的应用程序没有作为独立应用程序运行,则调用者可以对其做出反应并获得有关错误的信息。它也更容易进行调试,因为当你看到堆栈跟踪时,你也可以更好地了解出了什么问题。
需要注意的一件重要事情是,当异常达到顶级并因此导致VM退出时,VM返回的返回码为1,因此使用返回代码的应用程序外部会看到出现问题。
我认为System.exit()有意义的唯一情况是,您的应用程序是由非Java应用程序调用的,因此必须使用返回代码来查看您的应用程序是否有效,并且您需要这些应用程序应用程序有机会对不同的错误做出不同的反应,即您需要不同的返回代码。
答案 8 :(得分:0)
我也被迫添加一些盐。这是一个很棒的问题,在我编写应用程序时总是弹出。
正如这里的每个人似乎都同意的那样,您应谨慎使用System.exit()
,并在可能的情况下使用例外。但是,System.exit()
似乎仍然是将基本信息返回给系统的唯一方法,因此,如果要使应用程序可编写脚本,则这是必需的。如果您不需要它,只需抛出一个异常并加以处理即可。
但是,如果(且仅当)您的应用程序是单线程的,则可以使用它-可以确保没有其他东西进入,并且没有资源打开(至少在您持续使用{{ 3}}惯用语,我强烈建议这样做,因为它也使代码更简洁,更紧凑。)
另一方面,一旦您的应用程序创建了任何类型的可能写入资源的线程,System.exit()就会总计为“ no,no”,因为它可能(并且随着时间的推移)会破坏数据
为了能够使用多线程和脚本化的应用程序并仍保证数据完整性,到目前为止,我最好的解决方案是保存您创建的任何修改资源的线程(例如,通过始终使用添加线程的工厂方法) (到列表中),还安装了一个关闭钩子,该钩子通过中断并加入每个线程来干净地结束每个线程。由于System.exit()
也调用了shutdown钩子,因此可以保证(减去编程错误)在中间资源编写过程中不会杀死任何线程。
哦,是的,也许我什至不应该提及它,但是:永远不要使用那种可怕的System.halt()
方法。它只是将VM击中头部,而不会调用任何关机钩子。