4

私はコードから始めます。これはリフレクションを使用してメソッドを呼び出します

try {
    Method method = states.getClass().getDeclaredMethod(
            getCurrentStateId() + "_" + request.getEvent());
    states.setData(request, dataManager);
    method.invoke(states);
} catch (NoSuchMethodException e) {
    logger.debug("Method " + getCurrentStateId() + "_" + request.getEvent()
            + " cannot be found - invocation not performed.", e);
} catch (IllegalArgumentException e) {
    throw new InternalException("Method invocation with reflection failed.", e);
} catch (IllegalAccessException e) {
    throw new InternalException("Method invocation with reflection failed.", e);
} catch (InvocationTargetException e) {
    throw new InternalException("Method invocation with reflection failed.", e);
}

PropertiesDontMatchExceptionそして、 (ランタイム)をスローする次のコードでメソッドを呼び出します。

...
if (totalCredits < minimumCredits || totalCredits > maximumCredits) {
    throw new PropertiesDontMatchException("Minimum amount of credits=" + minimumCredits
            + ", maximum amount of credits=" + maximumCredits + ". Your amount of credits="                 + totalCredits + ". You have to modify your set of subjects.");
}
...

問題は、私のランタイム例外がInvocationTargetException最初のコードスニペットにラップされてキャッチされていることです。これは私が望むものではありません。しかし、ドキュメントによると、それは正しい動作です。

だから私はこの解決策を思いついた

...
} catch (InvocationTargetException e) {
    if (e.getCause() instanceof PropertiesDontMatchException) {
        throw (PropertiesDontMatchException) e.getCause();
    }
    throw new InternalException("Method invocation with reflection failed.", e);
}
...

これは私のランタイム例外を伝播する適切な方法ですか、それともこの問題のより良い解決策はありますか?

4

1 に答える 1

4

はい、これはこの場合の正しいエラー処理です。私はあなたのテストを拡張するだけですRuntimeException

} catch (InvocationTargetException e) {
    if (e.getCause() instanceof RuntimeException) {
        throw (RuntimeException) e.getCause();
    }
    if (e.getCause() instanceof Error) {
        throw (Error) e.getCause();
    }
    throw new InternalException("Method invocation with reflection failed.", e);
}

または、チェックされた例外にカスタムの代わりに使用してもかまわない場合は、代わりにThrowablesのユーティリティクラスを使用します。RuntimeExceptionInternalException

} catch (InvocationTargetException e) {
    throw Throwables.propagate(e.getCause());
}

IllegalAccessExceptionたとえば、メソッドのスローとリフレクションメカニズム自体がそれをスローすることを区別するために、追加のラッピングが必要です。

Future.get()同様のAPI設計の選択は、 -非同期ジョブからスローされExecutionExceptionた例外が実際の例外をラップしてスローされた場合に観察できます。

于 2012-04-13T20:44:10.897 に答える