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 はこう言っています: "このメソッドは正常に戻りません。"どういう意味ですか?
System.exit()
はプログラムが終了する前に shutdown hooks を実行するために使うことができます。これは、プログラムのすべての部分が互いを認識できない(そして認識すべきでない)場合に、より大きなプログラムでシャットダウンを処理するのに便利な方法です。それから、誰かが辞めたいのなら、彼は単にSystem.exit()
を呼び出すことができ、(適切に設定されていれば)シャットダウンフックはファイルを閉じる、リソースを解放するなどの必要なシャットダウンの儀式をすべて行うことに注意します。
「このメソッドは正常に戻りません。」メソッドが返されないことを意味します。一度スレッドがそこに行くと、それは戻ってきません。
プログラムを終了するもう1つの方法、おそらくもっと一般的な方法は、単にmain
メソッドの終わりに到達することです。しかし、デーモン以外のスレッドが実行されている場合、それらはシャットダウンされず、したがってJVMは終了しません。したがって、そのようなデーモン以外のスレッドがある場合、デーモン以外のすべてのスレッドをシャットダウンして他のリソースを解放するには、(シャットダウンフック以外の)何らかの手段が必要です。デーモン以外のスレッドが他にない場合は、main
から戻るとJVMがシャットダウンされ、シャットダウンフックが呼び出されます。
何らかの理由でシャットダウンフックは過小評価され誤解されたメカニズムであるように思われます、そして人々は彼らのプログラムをやめるためにあらゆる種類のプロプライエタリなカスタムハックでホイールを再発明しています。シャットダウンフックの使用をお勧めします。とにかく標準的な Runtime にすべて含まれています。
その場合は必要ありません。追加のスレッドは起動されません。終了コード(デフォルトは0)を変更していません - 基本的には意味がありません。
ドキュメントがメソッドが正常に返されないと言うとき、それはコンパイラがそれを知らないとしても、事実上到達不能であることを意味します。
System.exit(0);
System.out.println("This line will never be reached");
例外がスローされるか、またはVMが戻り前に終了します。決して「戻る」ことは決してありません。
System.exit()
IMEを呼び出す価値があることは非常にまれです。コマンドラインツールを書いていて、単に例外をスローするのではなく終了コードでエラーを示したいのであれば意味がありますが、通常の本番コードで最後に使用したときのことは思い出せません。 。
それは世界の終わりであり、あなたのコードのどれも次に実行されることはないので、メソッドは決して戻りません。
あなたのアプリケーションは、あなたの例では、とにかくコードの同じ場所で終了するでしょう、しかしあなたがSystem.exitを使用するならば。次のように、カスタムコードを環境に返すことができます。
System.exit(42);
誰があなたの終了コードを利用するつもりですか?アプリケーションを呼び出したスクリプト。 Windows、Unix、その他すべてのスクリプト環境で動作します。
なぜコードを返すのですか? 「成功しなかった」、「データベースが応答しなかった」などのことを言います。
od終了コードの値を取得し、それをunix Shellスクリプトまたはwindows cmdスクリプトで使用する方法を確認するには、このサイトでこの回答を確認してください
System.exit(0)
はJVMを終了します。このような単純な例では、違いを理解するのは困難です。このパラメータはOSに返され、通常は異常終了(ある種の致命的エラーなど)を示すために使用されます。したがって、バッチファイルまたはシェルスクリプトからJavaを呼び出すと、この値を取得してアイデアを得ることができますアプリケーションが成功した場合.
アプリケーションサーバーにデプロイされたアプリケーションでSystem.exit(0)
を呼び出した場合は、非常に大きな影響があります(試す前に考えてみてください)。
複雑なシャットダウンフックを持つ可能性があるアプリケーションでは、このメソッドを未知のスレッドから呼び出さないでください。 JVMが終了するまで呼び出しがブロックされるため、System.exit
は正常に終了しません。実行する前に、どんなコードが実行されていても、電源プラグが差し込まれているかのようです。 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();
}
System.exit(0)を呼び出さないでください。
ちなみに:0以外の戻りコードを返すことは、プログラムの異常終了を示したい場合には意味があります。
答えは本当に役に立ちましたが、いくらか余分な詳細を見逃していた方法もあります。上記の回答に加えて、以下がJavaでのシャットダウンプロセスの理解に役立つことを願っています。
シモンズ:JVMは整然とまたは突然のいずれかの方法でシャットダウンできます。
System.exitが必要です
あなたの場合、それは単純なmain-from-mainと全く同じことをします。
Java言語仕様 と言っている
プログラム終了
プログラムはすべてのアクティビティを終了させ、次の2つのうちの1つが起こると終了します。
デーモンスレッドではないスレッドはすべて終了します。
RuntimeまたはclassSystemクラスのexitメソッドを呼び出すスレッドがあり、その終了操作はセキュリティマネージャによって禁止されていません。
つまり、あなたが大きなプログラムを持っていて(少なくとも、これよりも大きい)、その実行を終了したいときには、それを使うべきです。
JVMで別のプログラムを実行していて、System.exitを使用している場合は、その2番目のプログラムも閉じられます。たとえば、クラスタノードでJavaジョブを実行し、そのクラスタノードを管理するJavaプログラムが同じJVMで実行されているとします。ジョブがSystem.exitを使用する場合は、ジョブを終了するだけでなく、「完全なノードをシャットダウンする」こともします。管理プログラムが誤って閉じられたため、そのクラスタノードに別のジョブを送信することはできません。
したがって、同じJVM内の別のJavaプログラムからプログラムを制御できるようにしたい場合は、System.exitを使用しないでください。
故意にJVM全体を閉じたい場合や、他の答えで説明されている可能性を利用したい場合(たとえばシャットダウンフック: Java shutdown hook 、non)には、System.exitを使用してください。コマンドライン呼び出しの-zero戻り値: WindowsバッチファイルでJavaプログラムの終了ステータスを取得する方法 )。
ランタイム例外も見てください。 System.exit(num)またはmainからRuntimeExceptionをスローしますか?