回答:
一般的にはありません。
ただし、特定のエラーをキャッチする必要がある場合があります。
フレームワーク風のコード(サードパーティのクラスをロードする)を作成している場合は、キャッチするのが賢明ですLinkageError
(クラス定義が見つからない、リンクに満足できない、互換性のないクラスの変更)。
のサブクラスをスローする愚かなサードパーティのコードもいくつか見たError
ので、それらも処理する必要があります。
ちなみに、から復旧できないかどうかはわかりませんOutOfMemoryError
。
決して。アプリケーションが次のコード行を実行できるかどうかを確認することはできません。を取得した場合OutOfMemoryError
、確実に何かを実行できるという保証はありません。RuntimeExceptionをキャッチして例外をチェックしましたが、エラーは発生しません。
boolean assertionsEnabled = false; assert assertionsEnabled = true;
通常は、常にキャッチjava.lang.Error
してログに書き込むか、ユーザーに表示する必要があります。私はサポートで働いており、プログラマーがプログラムで何が起こったかを知ることができないことを毎日見ています。
デーモンスレッドがある場合は、終了しないようにする必要があります。それ以外の場合、アプリケーションは正しく動作します。
java.lang.Error
最高レベルでのみキャッチする必要があります。
エラーのリストを見ると、ほとんどが処理できることがわかります。たとえば、ZipError
破損したzipファイルの読み取り時に発生します。
最も一般的なエラーはOutOfMemoryError
and NoClassDefFoundError
であり、どちらもほとんどの場合ランタイムの問題です。
例えば:
int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];
を生成できOutOfMemoryError
ますが、これは実行時の問題であり、プログラムを終了する理由はありません。
NoClassDefFoundError
ほとんどの場合、ライブラリが存在しない場合、または別のバージョンのJavaを使用している場合に発生します。プログラムのオプションの部分である場合は、プログラムを終了しないでください。
Throwable
トップレベルでキャッチし、有用なエラーメッセージを生成することがなぜ良いのかについて、さらに多くの例を挙げられます。
OutOfMemoryError
ランタイムエラーではないため、アプリケーションがエラーから回復できるという保証はありません。運new byte[largeNumber]
が良ければOOMを取得できますが、その割り当てがOOMを引き起こすのに十分でない場合は、次の行または次のスレッドでトリガーされる可能性があります。length
が信頼できない入力である場合、を呼び出す前に検証する必要があるため、これは実行時の問題new byte[]
です。
NoClassDefFoundError
コンパイルされたJavaコードがクラスを見つけられないときに呼び出されるため、どこでも発生する可能性があります。JDKが正しく構成されていない場合は、java.util.*
クラスを使用しようとすることがあり、それに対してプログラミングすることは事実上不可能です。オプションで依存関係を含める場合は、を使用ClassLoader
して、それが存在するかどうかを確認する必要がありClassNotFoundException
ます。
ZipError
クラスを含むjarファイルが破損したzipファイルであることを示します。これは非常に深刻な問題であり、現時点では実行されるコードを信頼することはできず、コードから「回復」しようとすることは無責任です。
java.lang.Error
かjava.lang.Throwable
、最上位でそれを使って何かをしようとすると役立ちます。たとえば、エラーメッセージをログに記録します。しかし、その時点では、これが実行されるという保証はありません。JVMがOOMである場合、ログを記録しようとすると、より多くString
のが割り当てられ、別のOOMがトリガーされます。
マルチスレッド環境では、ほとんどの場合、それをキャッチする必要があります。キャッチしたら、ログに記録して、アプリケーション全体を終了してください!これを行わないと、いくつかの重要な部分を実行している可能性があるスレッドが停止し、アプリケーションの残りの部分はすべて正常であると見なします。その中で、多くの望ましくない状況が発生する可能性があります。1つの最小の問題は、1つのスレッドが機能していないために他のスレッドがいくつかの例外をスローし始めた場合、問題の根本を簡単に見つけることができないことです。
たとえば、通常、ループは次のようになります。
try {
while (shouldRun()) {
doSomething();
}
}
catch (Throwable t) {
log(t);
stop();
System.exit(1);
}
場合によっては、さまざまなエラーを別の方法で処理する必要があります。たとえば、OutOfMemoryErrorでは、アプリケーションを定期的に閉じることができます(メモリを解放して続行することもできます)。
Error
通常はキャッチすべきではない、それは同様に、発生することはありません異常な状態を示します。
Error
クラスのJava API仕様から:
Error
サブクラスであるThrowable
ことが合理的なアプリケーションは、キャッチすべきではないという重大な問題を示します。このようなエラーのほとんどは異常な状態です。[...]これらのエラーは発生してはならない異常な状態であるため、メソッドのthrows句でメソッドの実行中にスローされてもキャッチされないErrorのサブクラスをメソッドで宣言する必要はありません。
仕様に記載されているように、Error
がスローされるのは、Error
発生した場合にアプリケーションで実行できることはほとんどなく、状況によっては、Java仮想マシン自体が不安定な状態になる場合があります(などVirtualMachineError
)
がError
サブクラスであるのThrowable
それがでキャッチすることができることを意味しtry-catch
たときにアプリケーションが異常な状態になりますよう、句が、それはおそらく本当に必要ありませんError
JVMによってスローされます。
セクション11.5 Java言語仕様の第2版の例外階層にも、このトピックに関する短いセクションがあります。
また、他にもエラーをキャッチした場合に再スローする必要がある場合がいくつかあります。たとえば、ThreadDeathは決してキャッチされるべきではありません。それは、含まれている環境(アプリケーションサーバーなど)でキャッチすると大きな問題を引き起こす可能性があります。
アプリケーションは、非同期的に終了した後にクリーンアップする必要がある場合にのみ、このクラスのインスタンスをキャッチする必要があります。ThreadDeathがメソッドによってキャッチされた場合、スレッドが実際に停止するように再スローすることが重要です。
Error
。
非常に、非常にまれです。
私は、非常に具体的な既知の1つのケースに対してのみそれを行いました。たとえば、2つの独立したClassLoaderが同じDLLをロードすると、java.lang.UnsatisfiedLinkErrorがスローされる可能性があります。(JARを共有クラスローダーに移動する必要があることに同意します)
しかし、最も一般的なケースは、ユーザーが不平を言うようになったときに何が起こったかを知るためにロギングが必要だったということです。静かに死ぬのではなく、ユーザーにメッセージまたはポップアップを送りたい。
C / C ++のプログラマーでさえ、エラーを表示し、終了する前に理解できないこと(たとえば、メモリ障害)を知らせます。
Androidアプリケーションでjava.lang.VerifyErrorをキャッチしています。私が使用しているライブラリは、古いバージョンのOSを搭載したデバイスでは機能せず、ライブラリコードはそのようなエラーをスローします。もちろん、実行時にOSのバージョンを確認することでエラーを回避できましたが、
テスト環境でjava.lang.AssertionErrorをキャッチするのは非常に便利です...
理想的には、エラーを処理/キャッチしないでください。ただし、フレームワークまたはアプリケーションの要件に基づいて、必要な場合があります。たとえば、より多くのメモリを消費するDOMパーサーを実装するXMLパーサーデーモンがあるとします。パーサースレッドのような要件がある場合、OutOfMemoryErrorを取得したときにスレッドを停止せず、処理して、アプリケーション/フレームワークの管理者にメッセージ/メールを送信する必要があります。