変数に例外があります(スローされません)。
最良の選択肢は何ですか?
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();
}
instanceof
を使用することをお勧めします。例外のスローは、複雑で費用のかかる操作です。 JVMは、例外しないでくださいが発生した場合に高速になるように最適化されています。例外は例外的でなければなりません。
throw
テクニックはおそらく示されているようにコンパイルされないことに注意してください。例外タイプがチェック済み例外である場合、コンパイラーはそのタイプをキャッチするか、またはスローされたものとして宣言する必要があると不平を言うでしょう(else { ... }
句に対応特定のサブタイプではない例外をどのように処理するかに応じて、instanceof
テクニックを使用します)。
みんなのバブルを破りたくないのですが、try/catch
を使うのは速いです。それが「正しい」方法であると言っているわけではありませんが、パフォーマンスが重要であれば、それが勝者です。以下は、次のプログラムの結果です。
実行1
実行2
実行
テスト環境
各実行のウォームアップサブランを割り引くと、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;
}
}
}
実際にプレーンオブジェクトを使用して「制約」を表すことを強くお勧めします。マーキングインターフェイス(例:Message
)またはJava.lang.String
あなた次第です。例外は、どちらかを機能させることができたとしても、意図したとおりに使用することを意図したものではありません(2番目はより高速であると予想されますが、時期尚早に最適化されます...)。
また、getCustomViolation()メソッドを含むカスタム例外のインターフェースを作成して、ポリモーフィズムを使用することもできます。次に、各カスタム例外はそのインターフェースとそのメソッドを実装します。