为什么我的代码中不需要使用System.exit(0)?

23 浏览
0 Comments

为什么我的代码中不需要使用System.exit(0)?

在Java中,以下代码中有无System.exit(0)有什么区别?\n

public class TestExit
{      
    public static void main(String[] args)
    { 
        System.out.println("hello world");
        System.exit(0);  // 是否必要?什么情况下必须调用? 
    }      
}

\n文档中说:\"该方法永远不会正常返回。\"这是什么意思?

0
0 Comments

为什么在我的代码中不需要使用System.exit(0)?

在代码的末尾使用System.exit(0)是没有必要的,因为此时程序已经到达了终点,后面的代码不会被执行到。

在你的示例中,即使不使用System.exit,你的应用程序也会在同一位置退出。但是,如果你使用System.exit,你可以选择返回一个自定义的退出代码给环境,比如:

System.exit(42);

谁会使用你的退出代码呢?调用应用程序的脚本。这在Windows、Unix和其他可脚本化的环境中都适用。

为什么要返回一个退出代码呢?可以用来表示诸如“我没有成功”、“数据库没有响应”等信息。

如果你想了解如何获取退出代码的值,并在Unix shell脚本或Windows cmd脚本中使用它,可以参考这个网站上的回答

更详细的解释可以参考stackoverflow.com/questions/28738307/…

0
0 Comments

为什么在我的代码中不需要使用System.exit(0)?

在这种情况下,不需要使用System.exit(0)。没有额外的线程被启动,您没有改变退出代码(默认为0) - 基本上是没有意义的。

当文档说该方法永远不会正常返回时,它意味着后续的代码行是无法到达的,尽管编译器并不知道这一点:

System.exit(0);

System.out.println("这行代码将永远不会被执行");

无论是抛出异常还是在返回之前终止,它都永远不会“只是返回”。

在我看来,很少需要调用System.exit()。如果您正在编写一个命令行工具,并且希望通过退出代码指示错误而不是抛出异常,那么这是有意义的...但我已经记不起上一次在正常的生产代码中使用它是什么时候了。

为什么编译器不知道这一点呢?System.exit()难道不足以引起特定的检测代码吗?

:不,我不这样认为。在语言中为这样的东西添加特殊情况会增加语言的复杂性,而几乎没有任何好处。

我以为“永远不会正常返回”与语句的“突然完成”有关。我错了吗?

:不,你是对的。System.exit()永远不会正常完成 - 它始终会以异常完成或VM关闭(这在JLS中并没有详细介绍)。

好吧,解释得很清楚,但JVM也会在任何时候调用它吗?如果不是,为什么他们提供了带参数的退出方法?我的意思是用户总是提供0而不是其他选项,如1到255。

:你为什么这么认为?完全有理由使用非0的值调用它,以向调用的shell(或其他)指示程序遇到错误。

我唯一想知道的是JVM在任何情况下是否内部调用它?

:不知道...您对什么效果感兴趣?

什么时候传递非零值?有任何情况吗?迄今为止,我看到的所有代码都是传递值0。

:正如我之前所说,通常是为了指示程序遇到错误。

0
0 Comments

为什么我的代码中不需要使用System.exit(0)?

System.exit()可以在程序退出之前运行shutdown hooks。这是处理大型程序中的关闭的一种方便方式,程序的各个部分无法(也不应该)相互了解。因此,如果有人想要退出,他可以简单地调用System.exit(),然后shutdown hooks(如果正确设置)会处理所有必要的关闭仪式,比如关闭文件、释放资源等。

"这个方法永远不会正常返回"意味着这个方法不会返回;一旦线程进入这个方法,它就不会回来了。

另一种更常见的退出程序的方法是简单地到达main方法的末尾。但是,如果有任何非守护线程在运行,它们将不会被关闭,因此JVM将不会退出。因此,如果您有任何此类非守护线程,您需要其他手段(而不是shutdown hooks)来关闭所有非守护线程并释放其他资源。如果没有其他非守护线程,从main方法返回将关闭JVM并调用shutdown hooks。

由于某种原因,shutdown hooks似乎是一种被低估和误解的机制,人们正在重新发明轮子,使用各种专有的自定义方法来退出他们的程序。我鼓励使用shutdown hooks;它们都在您将要使用的标准Runtime中。

"这个方法永远不会正常返回"意味着这个方法不会返回;一旦线程进入这个方法,它就不会回来了。特别要注意的是,这意味着您不能对调用System.exit(0)的方法进行单元测试...

-1 不正确。如果JVM正常终止,无论是因为System.exit还是main()的终止,shutdown hooks都会运行。参见zx81/doku/java/javadoc/j2se1.5.0/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)

:只有在存在其他非守护线程时,才会启动关闭机制,即在最后一个非守护线程终止之后。除非您明确调用System.exit(),否则不会触发关闭。这在Runtime文档中明确说明了。

请注意,如果您的shutdown hook依赖于调用System.exit的线程,可能会发生死锁。

还有一点要补充的是,如果有人停止运行时,shutdown hooks将不会运行(Runtime.getRuntime().halt())。

正如这里所提到的,shutdown hooks会被操作系统切断,不是一种非常可靠的阻止关闭的方式,即使在Windows上也是如此。它们也不适用于使用javaw时

:是的,如果您使用kill -9终止进程,那么shutdown hooks显然不会运行。关于javaw,那似乎是一些15年前针对Java 1.3报告的旧bug。我非常确定,无论您使用java.exe、javaw.exe还是Invocation API启动进程,shutdown hooks在本十年的Java中都能正常工作。

事实上,我自己从未遇到过javaw问题,所以对于这一点我感到抱歉;感谢您的澄清!关于操作系统的kill,我不确定是JVM还是操作系统的问题,但我确实遇到过shutdown hooks没有足够时间完成的问题,即使有一个我认为不是计算密集型的线程。

我的一个同事曾经向我展示了一个技巧,确保System.exit()会抛出一些安全异常而不是退出Java。不记得是什么了,但它允许他对可能调用System.exit()的方法进行单元测试。这仍然是不过度使用System.exit()的一个例子,我认为。

文章标题:为什么我的代码中不需要使用System.exit(0)?

System.exit()可以在程序退出之前运行shutdown hooks。这是处理大型程序中的关闭的一种方便方式,程序的各个部分无法(也不应该)相互了解。因此,如果有人想要退出,他可以简单地调用System.exit(),然后shutdown hooks(如果正确设置)会处理所有必要的关闭仪式,比如关闭文件、释放资源等。

另一种更常见的退出程序的方法是简单地到达main方法的末尾。但是,如果有任何非守护线程在运行,它们将不会被关闭,因此JVM将不会退出。因此,如果您有任何此类非守护线程,您需要其他手段(而不是shutdown hooks)来关闭所有非守护线程并释放其他资源。如果没有其他非守护线程,从main方法返回将关闭JVM并调用shutdown hooks。

由于某种原因,shutdown hooks似乎是一种被低估和误解的机制,人们正在重新发明轮子,使用各种专有的自定义方法来退出他们的程序。我鼓励使用shutdown hooks;它们都在您将要使用的标准Runtime中。

文章结束。

0