25

さまざまな理由から、 Java アプリケーションSystem.exitを作成する際に呼び出しが嫌われているため、すべてが計画どおりに進んでいないことを呼び出しプロセスに通知するにはどうすればよいでしょうか?

編集: 1 はstandinゼロ以外の終了コードです。

4

9 に答える 9

32

「アプリケーション」が実際にはより大きな Java アプリケーション (サーバー) のサブアプリケーション (サーブレット、アプレットなど) である場合、の使用System.exitは嫌われます。この場合、System.exitは JVM を停止し、他のすべてのサブアプリケーションも停止する可能性があります。この状況では、適切な例外をスローすることが最善の選択肢です。これは、アプリケーション フレームワーク/サーバーによってキャッチされ、処理される可能性があります。

Java アプリケーションが本当にスタンドアロン アプリケーションとして実行されることを意図している場合は、 を使用しても問題はありませんSystem.exit。この場合、終了値を設定することは、失敗または成功を親プロセスに伝える最も簡単な (そして最もよく使われる) 方法です。

于 2008-08-28T18:25:27.760 に答える
10

「例外をスローする」群衆に同意します。その理由の 1 つは、System.exit を呼び出すと、他のコードで使用できるようにしたい場合にコードが使いづらくなることです。たとえば、あなたのクラスが Web アプリやある種のメッセージを消費するアプリから有用であることがわかった場合、それらのコンテナーが何らかの形で失敗に対処できるようにするとよいでしょう。コンテナーは、操作を再試行したり、ログに記録して問題を無視したり、管理者に電子メールを送信したりする必要がある場合があります。

これに対する例外は、あなたのmain()方法です。これにより、例外がトラップSystem.exit()され、呼び出し元のプロセスまたはシェル スクリプトが認識できる値で呼び出される可能性があります。

于 2008-08-28T18:25:11.770 に答える
2

例外をスローすることは、何か問題が発生したときにすべきことだと思います。このようにして、アプリケーションがスタンドアロン アプリとして実行されていない場合、呼び出し元はそれに反応し、問題に関する情報を得ることができます。また、スタック トレースが表示されると何が問題なのかをよりよく理解できるため、デバッグが容易になります。

注意すべき重要な点の 1 つは、例外がトップ レベルに達したために VM が終了した場合、VM は戻りコード 1 を返すため、戻りコードを使用する外部のアプリケーションは何か問題が発生したことを確認できるということです。

System.exit() が理にかなっていると私が思う唯一のケースは、あなたのアプリがJavaではないアプリケーションによって呼び出されることを意図しているため、リターンコードを使用してアプリが機能したかどうかを確認する必要があり、それらのアプリケーションにさまざまな問題が発生した場合に異なる反応を示す可能性があります。つまり、異なるリターン コードが必要です。

于 2008-08-29T07:57:58.667 に答える
2

当社のポリシーでは、System.exit(-1) を呼び出しても問題ありません (むしろ推奨されます) が、init() メソッド内でのみです。プログラムの通常のフロー中に呼び出す前に、私は間違いなくよく考えます。

于 2008-08-28T17:03:15.273 に答える
1

Web サーブレット環境でも危険/問題になる可能性があります。

例外をスローすることは、一般的に他の選択肢と見なされます。

于 2008-08-28T16:57:02.950 に答える
1

例外をスローすることは、特定のエラーに関する情報をアプリ内外に送信する最良の方法です。

数字だけでは次のことはわかりません。

Exception at thread 'main': FileNotFoundException "The file 'foo' doesn't exist"

(またはそれに近いもの)

于 2008-08-28T17:05:22.447 に答える
0

通常の出口では眉をひそめています。「すべてが計画どおりに進んでいない」場合は、System.exit で問題ありません。

更新:あなたの「1」には、どこかに文書化されている意味があると思います。

于 2008-08-28T16:53:44.843 に答える
0

私も自分の塩を少し加えたいと思っています。これは、私がアプリケーションを作成するときに常に出てくる素晴らしい質問です。

ここにいる全員が同意しているように、 の使用には注意しSystem.exit()、可能であれば例外を使用する必要があります。ただし、System.exit()基本的な情報をシステムに返す唯一の方法であるように思われるため、アプリケーションをスクリプト可能にしたい場合は必要です。それが必要ない場合は、例外をスローして処理を完了してください。

しかし、アプリケーションがシングル スレッドである場合 (およびその場合のみ)、それを使用しても問題ありません。他のものが入ってこないこと、リソースが開かれていないことが保証されます (少なくとも、一貫してtry-with-resource を使用している場合)。これは、コードをよりクリーンでコンパクトにするため、強くお勧めします)。

一方、アプリケーションがリソースを書き込む可能性のあるスレッドを作成するとすぐに、 System.exit() は完全に「いいえ、いいえ」になります。これは、データが破損する可能性がある (そして時間の経過とともに破損する可能性がある) ためです。

マルチスレッドおよびスクリプト化されたアプリケーションを使用できるようにし、データの整合性を保証するには、これまでの私の最善の解決策は、作成したリソース変更スレッドを保存することです (たとえば、スレッドをリストに追加するファクトリ メソッドを一貫して使用することによって) )、また、各スレッドを中断して結合することにより、各スレッドをきれいに終了させるシャットダウンフックもインストールします。シャットダウン フックも によって呼び出されるSystem.exit()ため、リソースの書き込み中にスレッドが強制終了されないことが (プログラミング エラーを除いて) 保証されます。

そうそう、私はそれについて言及するべきではないかもしれませんが、決して、絶対に、その恐ろしいSystem.halt()方法を使用しないでください. VM の頭を撃つだけで、シャットダウン フックは呼び出されません。

于 2020-03-24T07:03:25.617 に答える