25

変数に例外があります (スローされません)。

最良の選択肢は何ですか?

Exception exception = someObj.getExcp();
try {
    throw exception;
} catch (ExceptionExample1 e) {
    e.getSomeCustomViolations();
} catch (ExceptionExample2 e) {
    e.getSomeOtherCustomViolations(); 
}

また

Exception exception = someObj.getExcp();
if (exception instanceof ExceptionExample1) {
    exception.getSomeCustomViolations();
} else if (exception instanceof ExceptionExample2) {
    exception.getSomeOtherCustomViolations();
}
4

4 に答える 4

13

instanceofより高速になる可能性が高いため、使用することをお勧めします。例外のスローは、複雑でコストのかかる操作です。JVM は、例外が発生しない場合に高速になるように最適化されています。例外は例外的であるべきです。

このthrow手法はおそらく示されているようにコンパイルされないことに注意してください。例外の型がチェック済み例外である場合、コンパイラは、その型をキャッチするか、スローされたものとして宣言する必要があると不平を言います (手法else { ... }を使用する場合は節に対応します)。instanceofまたは、特定のサブタイプの 1 つではない例外を処理する方法によっては、役に立たない場合があります。

于 2013-12-06T19:09:46.503 に答える
12

みんなのバブルを破裂させるのは嫌いですが、使用した方try/catch速いです。それが「正しい」方法だと言っているわけではありませんが、パフォーマンスが重要な場合は、それが勝者です。以下は、次のプログラムの結果です。

実行 1

  • サブラン 1: Instanceof : 130 ミリ秒
  • サブラン 1: トライ/キャッチ: 118 ms
  • サブラン 2: Instanceof : 96 ミリ秒
  • サブラン 2: トライ/キャッチ: 93 ms
  • サブラン 3: Instanceof : 100 ミリ秒
  • サブラン 3: トライ/キャッチ: 99 ms

実行 2

  • サブラン 1: Instanceof : 140 ミリ秒
  • サブラン 1: トライ/キャッチ: 111 ms
  • サブラン 2: Instanceof : 92 ミリ秒
  • サブラン 2: トライ/キャッチ: 92 ms
  • サブラン 3: インスタンスオブ : 105 ミリ秒
  • サブラン 3: トライ/キャッチ: 95 ms

実行 3

  • サブラン 1: Instanceof : 140 ミリ秒
  • サブラン 1: トライ/キャッチ: 135 ms
  • サブラン 2: Instanceof : 107 ミリ秒
  • サブラン 2: トライ/キャッチ: 88 ms
  • サブラン 3: Instanceof : 96 ミリ秒
  • サブラン 3: トライ/キャッチ: 90 ms

テスト環境

  • Java: 1.7.0_45
  • Mac OS X マーベリックス

各実行のウォームアップ サブランを割り引くと、このinstanceof方法ではせいぜい のパフォーマンスしか達成できませんtry/catch。この方法の平均 (ウォームアップを除く)instanceofは 98 ミリ秒で、 の平均try/catchは 92 ミリ秒です。

各メソッドをテストする順序を変えていないことに注意してください。私は常に のブロックをテストし、instanceof次に のブロックをテストしましたtry/catch。これらの調査結果と矛盾する、または確認する他の結果が見られることを楽しみにしています。

public class test {

    public static void main (String [] args) throws Exception {
        long start = 0L;
        int who_cares = 0; // Used to prevent compiler optimization
        int tests = 100000;

        for ( int i = 0; i < 3; ++i ) {
            System.out.println("Testing instanceof");
            start = System.currentTimeMillis();
            testInstanceOf(who_cares, tests);
            System.out.println("instanceof completed in "+(System.currentTimeMillis()-start)+" ms "+who_cares);

            System.out.println("Testing try/catch");
            start = System.currentTimeMillis();
            testTryCatch(who_cares, tests);
            System.out.println("try/catch completed in "+(System.currentTimeMillis()-start)+" ms"+who_cares);
        }
    }

    private static int testInstanceOf(int who_cares, int tests) {
        for ( int i = 0; i < tests; ++i ) {
            Exception ex = (new Tester()).getException();
            if ( ex instanceof Ex1 ) {
                who_cares = 1;
            } else if ( ex instanceof Ex2 ) {
                who_cares = 2;
            }
        }
        return who_cares;
    }

    private static int testTryCatch(int who_cares, int tests) {
        for ( int i = 0; i < tests; ++i ) {
            Exception ex = (new Tester()).getException();
            try {
                throw ex;
            } catch ( Ex1 ex1 ) {
                who_cares = 1;
            } catch ( Ex2 ex2 ) {
                who_cares = 2;
            } catch ( Exception e ) {}
        }
        return who_cares;
    }

    private static class Ex1 extends Exception {}

    private static class Ex2 extends Exception {}

    private static java.util.Random rand = new java.util.Random();

    private static class Tester {
        private Exception ex;
        public Tester() {
            if ( rand.nextBoolean() ) {
                ex = new Ex1();
            } else {
                ex = new Ex2();
            }
        }
        public Exception getException() {
            return ex;
        }
    }
}
于 2013-12-06T20:35:53.900 に答える