5

Java アプリケーションですべての例外をインターセプトする最も簡単な方法は何ですか? この種の機能を提供するには AOP が必要ですか、それとも動的プロキシで実行できますか、それとも別の方法がありますか? 最も単純なソリューションは、実行パフォーマンスへの影響に関しても優れたソリューションですか? この件に関する技術的なノウハウを把握しようとしているので、より経験豊富な開発者から可能な解決策を聞きたいです。

編集:

すでに良いアドバイスをありがとうございますが、現在のアドバイスはチェック例外にのみ適用されますか? NullPointerExceptions のような未チェックの例外についてはどうでしょうか? これらがキャッチされ、キャッチされたアプリケーションがヒープ/スタックをダンプして、クラッシュの瞬間にアプリケーションの現在のコンテキストを提供すると便利ではないでしょうか?

4

7 に答える 7

11

すべての例外を傍受したい目的は何ですか - ロギング、エラー報告のためですか?

Java プログラムのすべての行ですべての例外をインターセプトすることは可能ですが、おそらくパフォーマンスに大きな影響を与えるでしょう。やむを得ない場合は、コンパイル時に実行できる (つまり、クラス ファイルに「織り込む」) ことができ、動的プロキシよりもはるかに高速なAspectJなどを使用することをお勧めします。

しかし、それは私が絶対に避けようとすることです!一般に、キャッチしたい例外の範囲を制限する方が良いと思います。また、GUI アプリケーションでエラー ダイアログを表示するのに役立つことがわかっているThread.setDefaultUncaughtExceptionHandlerを調べることもできます。

于 2009-10-02T13:05:12.293 に答える
9

Phil の回答と同様に、キャッチされていない例外ハンドラーの使用方法を示すサンプル コードを次に示します。これは、チェックされた例外とチェックされていない例外の両方で機能します。

編集: 質問の更新されたコメントに基づいてスタック トレースを出力するように更新されました。

import java.lang.Thread.UncaughtExceptionHandler;

public class Test {

    public static void main(String[] args) throws Exception {
        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {

            @Override
            public void uncaughtException(Thread t, Throwable e) {
                e.printStackTrace();
            }}

        );

        // throw new RuntimeException(); /* this works too */
        throw new Exception();
    }

}
于 2009-10-02T13:23:06.370 に答える
5

ネイトとコナミマンで...あなたが提案していることはまったく機能せず、OPの質問に答えません.

OP が try/catch 内から新しいスレッドを開始するとどうなりますか?

例えば:

public static void main(String[] args) {
    try {
        final Thread t = new Thread( new Runnable() {
            public void run() {
                System.out.println( 3 / Math.min(0,4) );
            }
        } );
        t.start();
    catch(Throwable t) {
        ...
    }
}

次に、例外をキャッチしていません。

これを行う正しい方法は、Thread.setDefaultUncaughtExceptionHandler を使用することです。

于 2009-10-02T13:49:41.523 に答える
3
public static void main(String[] args) {
    try {
        ...
    catch(Throwable t) {
        ...
    }
}
于 2009-10-02T13:00:56.897 に答える
0

単にすべての例外をキャッチするよりも重要なのは、例外をキャッチする場所です。

  1. 何かできることがない限り、例外をキャッチしないでください。それについて何もできない場合は、次のレベルまでバブルアップさせるか、キャッチして、より具体的な例外として再ラップし、再スローします。

  2. どこでも処理できないエラーをキャッチするために、常にグローバルな例外処理ブロック (Nate の回答のように) を用意して、ある程度正常に失敗できるようにします。

于 2009-10-02T13:05:41.483 に答える
0

すべての例外をキャッチする必要性を疑問視するすべての人に...

すべての例外をキャッチする正当な理由はたくさんあります。

  • GUIアプリでダイアログを表示して問題について話していると誰かが言及しました
  • 本当に必要なサードパーティ API のバグを回避する
  • 一部の JVM 実装のバグに対処する
  • 自己修復ソフトウェア。
  • 自動オンライン例外報告。

Java自体が EDT (イベント ディスパッチ スレッド) 上のすべての例外をインターセプトし、EDT が終了すると新しい EDT を生成することに注意してください。これは一種の「自己修復」ソフトウェアと見なすことができます。EDT の停止は前例のないことではなく、(逆に) アプリケーションの正常な実行を正確に妨げるものでもありません。(そして、そうです、Swing と AWT にはかなりのバグがあります。Sun のバグ パレードを見てください ;)

自尊心のあるソフトウェアは、予期しない例外の場合を実際に考慮に入れるべきであると主張することができます (あなたが出荷するすべてのソフトウェアは、100% バグがなく、新しいリリースやバグ修正リリースを取得することはありませんか?)予期しない例外が発生します。

「スマートな何か」は、ソフトウェアのクラッシュを防ぎ (EDT の場合のように)、ユーザーに警告し、レポートを送信するなどです。

そのようなことをする必要性を疑問視する回答、または私見が改造された場合にそうするのは悪い習慣であることを示唆する回答.

于 2009-10-02T14:05:22.440 に答える