1. ホーム
  2. java

[解決済み] Java の System.exit() は try/catch/finally ブロックでどのように動作するのでしょうか?重複

2023-05-10 17:15:48

質問

try/catch/finallyブロックでのreturn、つまりtryやcatchブロックでのreturnが実行されるべき場合でも、finallyでのreturnが常にそのメソッドのreturnとなるケースは頭打ちですね。

しかし、System.exit() にも同じことが当てはまるのでしょうか?例えば、tryブロックがあったとして。

try {
    //Code
    System.exit(0)
}
catch (Exception ex) {
    //Log the exception
}
finally {
    System.exit(1)
}

例外が発生しない場合、どのSystem.exit()が呼ばれるでしょうか?exitがreturn文であれば、System.exit(1)という行が常に(?)呼ばれることになるはずです。しかし、exitがreturnと異なる挙動をするかどうかはわかりません。

このコードは再現が不可能ではないにしろ、非常に難しい極端なケースにあるので、ユニットテストは書けません。今日後半に、もし空き時間があれば、実験を実行しようと思っていますが、とにかく気になるので、おそらく SO の誰かが答えを知っていて、実験を実行する前に、または実験を実行できない場合に、それを提供することができます。

どのように解決するのですか?

いいえ。 System.exit(0) は返らず、finallyブロックは実行されません。

System.exit(int) を投げることができます。 SecurityException . もしそうなった場合、最終的にブロック が実行されます。そして、同じプリンシパルが同じコードベースから同じメソッドを呼び出しているので、別の SecurityException がスローされる可能性があります。


2番目のケースの例です。

import java.security.Permission;

public class Main
{

  public static void main(String... argv)
    throws Exception
  {
    System.setSecurityManager(new SecurityManager() {

      @Override
      public void checkPermission(Permission perm)
      {
        /* Allow everything else. */
      }

      @Override
      public void checkExit(int status)
      {
        /* Don't allow exit with any status code. */
        throw new SecurityException();
      }

    });
    System.err.println("I'm dying!");
    try {
      System.exit(0);
    } finally {
      System.err.println("I'm not dead yet!");
      System.exit(1);
    }
  }

}