在Java中,以下代码中是否有System.exit(0)
有什么区别?
public class TestExit
{
public static void main(String[] args)
{
System.out.println("hello world");
System.exit(0); // is it necessary? And when it must be called?
}
}
document说:“此方法永远不会正常返回。”这是什么意思?
答案 0 :(得分:195)
System.exit()
可用于运行shutdown hooks。这是在较大程序中处理关闭的一种方便方法,其中程序的所有部分都不能(并且不应该)彼此了解。然后,如果有人想要退出,他可以简单地调用System.exit()
,并且关闭挂钩(如果正确设置)负责执行所有必要的关机仪式,例如关闭文件,释放资源等。
“此方法永远不会正常返回。”意味着该方法不会返回;一旦一个线程进入那里,就不会再回来了。
退出程序的另一种可能更常见的方法是简单地到达main
方法的末尾。但是如果有任何非守护程序线程在运行,它们将不会被关闭,因此JVM将不会退出。因此,如果您有任何此类非守护程序线程,则需要一些其他方法(而不是关闭挂钩)来关闭所有非守护程序线程并释放其他资源。如果没有其他非守护程序线程,则从main
返回将关闭JVM并将调用关闭挂钩。
出于某种原因,关机钩子似乎是一种被低估和误解的机制,人们正在用各种专有的自定义黑客重新发明轮子来退出他们的程序。我鼓励使用关机钩子;无论如何,你将会使用标准的Runtime。
答案 1 :(得分:48)
在这种情况下,不需要它。没有额外的线程会被启动,你没有更改退出代码(默认为0) - 基本上它没有意义。
当文档说方法永远不会正常返回时,这意味着后续的代码行有效无法访问,即使编译器不知道:
System.exit(0);
System.out.println("This line will never be reached");
将抛出异常,或者VM将在返回之前终止。它永远不会“回归”。
值得调用System.exit()
IME是非常罕见的。如果您正在编写命令行工具,并且想要通过退出代码指示错误而不是仅仅抛出异常,这是有意义的...但我不记得上次我在正常的生产代码中使用它了
答案 2 :(得分:15)
该方法永远不会返回,因为它是世界的末日,并且下一个代码都不会被执行。
在您的示例中,您的应用程序无论如何都会在代码中的相同位置退出,但是,如果您使用System.exit。您可以选择将自定义代码返回到环境,例如
System.exit(42);
谁将使用您的退出代码?一个调用应用程序的脚本。适用于Windows,Unix和所有其他可编写脚本的环境。
为什么要返回代码?要说“我没有成功”,“数据库没有回答”。
要了解如何获取退出代码的值并在unix shell脚本或windows cmd脚本中使用它,您可以检查this answer on this site
答案 3 :(得分:14)
System.exit(0)
终止JVM。在这样的简单例子中,很难理解差异。该参数被传递回OS并且通常用于指示异常终止(例如某种致命错误),因此如果您从批处理文件或shell脚本调用java,您将能够获得此值并获得一个想法如果申请成功。
如果您在部署到应用程序服务器的应用程序上调用System.exit(0)
(在尝试之前考虑它),那将会产生相当大的影响。
答案 4 :(得分:10)
在可能具有复杂关闭挂钩的应用程序中,不应从未知线程调用此方法。 System.exit
永远不会正常退出,因为调用将阻塞,直到JVM终止。就像任何正在运行的代码一样,在它完成之前将电源插头拉到上面。调用System.exit
将启动程序的关闭挂钩,并且调用System.exit
的任何线程都将阻塞,直到程序终止。这意味着如果关闭钩子又将一个任务提交给调用System.exit
的线程,程序将会死锁。
我在我的代码中处理了以下内容:
public static void exit(final int status) {
new Thread("App-exit") {
@Override
public void run() {
System.exit(status);
}
}.start();
}
答案 5 :(得分:7)
虽然答案确实很有帮助,但有些人错过了一些额外的细节。我希望下面除了上面的答案之外,还将帮助理解java中的关闭过程:
PS:JVM可以以有序或突然方式关闭。
答案 6 :(得分:6)
永远不应该调用System.exit(0)。
顺便说一下:如果你想表明程序异常终止,那么返回其他返回码比0更有意义。
答案 7 :(得分:5)
需要System.exit
在你的情况下,它与简单的从主回归完全相同。
答案 8 :(得分:4)
程序退出
程序终止其所有活动,并在两件事之一时退出 发生的情况:
所有不是守护程序线程的线程都会终止。
某些线程调用Runtime类或类 System 的exit方法, 并且安全管理员不禁止退出操作。
这意味着你应该在拥有大型程序时使用它(好吧,至少比这个程序大)并且想要完成它的执行。
答案 9 :(得分:3)
如果您在JVM中运行了另一个程序并且使用了System.exit,那么第二个程序也将关闭。例如,假设您在群集节点上运行java作业,并且管理群集节点的Java程序在同一JVM中运行。如果作业将使用System.exit,它不仅会退出作业,而且还会关闭整个节点"。由于管理程序被意外关闭,您将无法向该群集节点发送另一个作业。
因此,如果您希望能够从同一JVM中的另一个Java程序控制您的程序,请不要使用System.exit。
如果要故意关闭完整的JVM并且想要利用其他答案中描述的可能性(例如,关闭挂钩:Java shutdown hook,非零,请使用System.exit命令行调用的返回值:How to get the exit status of a Java program in Windows batch file)。
另请参阅运行时异常:System.exit(num) or throw a RuntimeException from main?