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

时间:2012-01-04 16:53:47

标签: 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.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类beta.main(arg1)块内的System.exit(0),因此永远无法访问代码finally。 由于alpha和beta是独立应用程序,当它们单独执行时,它们应该在程序结束时终止服务。 所以现在有任何方法可以在不改变alpha和beta类的实际功能的情况下到达beta.main(arg1)行。

如果您需要更多详细信息,请告知我们。 提前谢谢......

4 个答案:

答案 0 :(得分:4)

在这种情况下,可以使用shutdown hook:

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();
        }
    }
}

答案 1 :(得分:2)

(理想情况下,任何属于模块的公共API的任何内容都不应该执行任何调用exit的操作,并且类的main方法应该只是一个调用其他内容的小垫片在产生正确的退出代码之前的真正工作。)

也就是说,如果您想阻止System.exit,可以注册SecurityManager,将System.exit的来电转换为SecurityExceptionError

System.exit

  

<强>引发

     

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

这样的东西
System.setSecurityManager(new SecurityManager() {
  @Override
  public void checkExit(int exitCode) throws SecurityException {
    throw new SecurityException("stop that");
  }
});

然后调用main方法的方法可以捕获并抑制SecurityException。您可以通过创建自己的ExitCalledError并将其抛出而仅抑制它来使其更强大。

我发现这对于防止单位测试跑步者在测试运行时由{0}被测试代码exit以及零退出代码进行虚假报告成功非常有用。

答案 2 :(得分:1)

真的,唯一的解决办法是摆脱System.exit()调用。这就是System.exit()是邪恶的原因。替换它们的一个好方法是抛出异常 - 你可以向系统添加一个异常处理程序(看看将它们添加到ThreadGroups以为每个异常路径添加一个)然后决定你想要做什么。

答案 3 :(得分:0)

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