1文で2種類の例外をスローする
メソッドの引数を検査する時など、何種類かの例外を投げ分けたい場合があります。
これはなるべく短くしたいですね。
そこで1文で書いてみましょう。
package test; public class Throw2Test { @SuppressWarnings("serial") static class HogeException extends Exception {/**/} @SuppressWarnings("serial") static class FugaException extends Exception {/**/} // 例外スローを式にするためのメソッド public static <A, E extends Exception> A throwE(final E e) throws E { throw e; } // 何もしない public static <A> void doNothing(@SuppressWarnings("unused") final A a) {/**/} private static boolean cond() { return true; } public static void main(final String[] args) throws HogeException, FugaException { // (1) 2文 try { if(cond()) { throw new HogeException(); } throw new FugaException(); } catch (HogeException e) { e.printStackTrace(); } catch (FugaException e) { e.printStackTrace(); } // (2) throwのオペランドを条件式に try { throw cond() ? new HogeException() : new FugaException(); } catch (Exception e) { // Exceptionを処理する必要がある e.printStackTrace(); } // (3) 条件式の中で例外をスローする式 doNothing(cond() ? throwE(new HogeException()) : throwE(new FugaException())); } }
(1) throw は文なので、if文で条件分岐をすると2文が必要になってしまいます。
(2) throwのオペランドを条件式にすると、条件式の型が2種類の例外の共通のスーパークラスになってしまい、
Exceptionを処理する必要が生じます。
これはHogeExceptionとFugaExceptionを処理すればよかった(1)よりも重いです。
(3) そこで、実行時例外スローを式にと同様に*1例外スローを行うジェネリックなメソッドを用意します。(ここではthrowE)
メソッド呼び出しは式なので、条件式の中で使えます。
ただし条件式は文ではないので、文にするために適当なメソッド(ここではdoNothing())に渡してあげます。
以上、1文で2種類の例外をスローすることができました。
*1:今回は検査例外用に型パラメータが増えています