Java 如何在finally块中调用Sytem.exit(0)后运行代码

Java 如何在finally块中调用Sytem.exit(0)后运行代码,java,Java,我有三个类,比如alpha、beta、gamma,这三个类中的每一个都有一个main方法 alpha和beta类在其main方法中都有一个try…catch…finally块,如: public class alpha{ public static void main(String[] args){ try{ Do something; }catch(Exception ex){ ex.printStack

我有三个类,比如alpha、beta、gamma,这三个类中的每一个都有一个
main
方法

alpha和beta类在其
main
方法中都有一个
try…catch…finally
块,如:

public class alpha{

    public static void main(String[] args){
        try{
            Do something;
        }catch(Exception ex){
            ex.printStackTrace();
        }
        finally{
            System.exit(0);
        }
    }
}


public class beta{

    public static void main(String[] args){
        try{
            Do something;
         }catch(Exception ex){
            ex.printStackTrace();
        }
        finally{
            System.exit(0);
        }
    }
}
现在在gamma类中,我调用alpha和beta类的主要方法来连续运行,如下所示

public gamma{

    public static void main(String[] args) {
        try {
            alpha.main(arg);
            beta.main(arg1);
        } catch (Exception e) {
            e.printStackTrace();
        }
}
问题是由于alpha类的
finally
块中的
系统退出(0)
导致无法到达code
beta.main(arg1)
。 由于alpha和beta在单独执行时是独立的应用程序,因此它们应该在程序结束时终止服务。 因此,现在有任何方法可以到达
beta.main(arg1)
行,而不需要对alpha和beta类的实际功能进行太多更改

如果你需要更多的细节,请告诉我。 提前感谢…

(理想情况下,模块公共API的任何部分都不应该做任何调用
exit
的事情,类的
main
方法应该只是一个小垫片,在生成正确的退出代码之前调用其他执行实际工作的方法。)

也就是说,如果要阻止
System.exit
,可以注册一个
SecurityManager
,将调用转换为
System.exit
SecurityException
s或
Error
s

:

投掷

SecurityException
-如果安全管理器存在并且其
checkExit
方法不允许以指定状态退出

差不多

System.setSecurityManager(new SecurityManager() {
  @Override
  public void checkExit(int exitCode) throws SecurityException {
    throw new SecurityException("stop that");
  }
});
然后调用main方法的方法可以捕获并抑制
SecurityException
。您可以通过创建自己的
ExitCalledError
并抛出它,而只抑制它,使它更加健壮


我发现这对于防止单元测试运行程序错误地报告成功非常有用,因为测试运行程序被测试中的代码以零退出代码退出。

实际上,唯一的解决方案是取消System.exit()调用。这就是为什么System.exit()是邪恶的。替换它们的一个好方法是抛出一个异常——您可以向系统中添加一个异常处理程序(查看将它们添加到ThreadGroup中,以便为每个异常路径添加一个异常处理程序),然后决定要执行的操作。

system.exit(0)
终止当前运行的Java虚拟机。它关闭VM上的所有应用程序,而不仅仅是调用
System.exit(0)
的应用程序。您需要为您的功能考虑替代方案。这里有一个关于它的链接

在这种情况下,可以使用停机挂钩:

public class Gamma{

    public static void main(String[] args) {
        try {
        Thread hook = new Thread() { public void run() { Beta.main(args); } };
            hook.setDaemon(true);
            Runtime.getRuntime().addShutdownHook(hook);
            Alpha.main(args);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Hm的可能复制品。我无法决定我对此的看法——我讨厌使用SecurityManager做非安全性的事情,但这是一种优雅的黑客行为。@CharlieMartin,我同意这是一种黑客行为。尽管有黑客攻击,它还是相当健壮的,而且一些担心,测试运行者反馈的可靠性,在我看来是值得的。当然也有一些问题——仅仅是
SecurityManager
的存在就可能会挑起库代码中的细微错误,并影响VM优化事物的方式。好吧,我对它投了赞成票。但我还没决定我对它的看法。很好。我从未想过使用关机挂钩作为延续机制。嗨,弗拉德…我还有一个问题。。。当alpha.main(args)和beta.main(args)同时执行时,如何结束代码的服务。??提前感谢…您的程序执行得非常完美,正如我所希望的,但唯一的问题是gamma类在执行完语法后应该结束服务(与System.exit(0)相同)。你能帮上忙吗。。。。?谢谢…接得好。。。我已经更新了代码。钩子线程应该是守护进程,以不阻止最终系统。退出(0)。嗨,弗拉德,谢谢你的回复。。。有些人认为,即使将守护进程设置为true,程序也不会终止。您的代码是否缺少某些内容。。请帮帮我。谢谢