複数の例外をキャッチし、例外を再スローするJavaの方法
Java 7では、catchブロックが改良され、複数の例外を1つのcatchブロックで処理できるようになりました。複数の例外をキャッチしており、それらが似たコードを持っている場合、この機能を使用するとコードの重複を減らすことができます。実際の例を使って、Javaの複数例外のキャッチ機能を理解しましょう。
Javaで複数の例外をキャッチする
Java 7以前では、以下のようにして複数の例外を一つずつキャッチしていました。
catch (IOException ex) {
logger.error(ex);
throw new MyException(ex.getMessage());
catch (SQLException ex) {
logger.error(ex);
throw new MyException(ex.getMessage());
}
Java 7では、次のようにして、これらの例外をひとつのcatchブロックで捕捉することができます。
catch(IOException | SQLException ex){
logger.error(ex);
throw new MyException(ex.getMessage());
}
複数の例外を処理するキャッチブロックがある場合には、パイプ(|)を使ってそれらを区切ることができます。また、この場合、例外パラメータ(ex)はfinalであるため、変更することはできません。この機能によって生成されるバイトコードは小さくなり、コードの冗長性も減ります。
Javaの例外再スロー
他の改善点は、コンパイラの再スロー例外の解析です。Javaの再スロー例外では、メソッド宣言のthrows節でより具体的な例外タイプを指定することができます。小さな例を見てみましょう。
package com.scdev.util;
public class Java7MultipleExceptions {
public static void main(String[] args) {
try{
rethrow("abc");
}catch(FirstException | SecondException | ThirdException e){
//below assignment will throw compile time exception since e is final
//e = new Exception();
System.out.println(e.getMessage());
}
}
static void rethrow(String s) throws FirstException, SecondException,
ThirdException {
try {
if (s.equals("First"))
throw new FirstException("First");
else if (s.equals("Second"))
throw new SecondException("Second");
else
throw new ThirdException("Third");
} catch (Exception e) {
//below assignment disables the improved rethrow exception type checking feature of Java 7
// e=new ThirdException();
throw e;
}
}
static class FirstException extends Exception {
public FirstException(String msg) {
super(msg);
}
}
static class SecondException extends Exception {
public SecondException(String msg) {
super(msg);
}
}
static class ThirdException extends Exception {
public ThirdException(String msg) {
super(msg);
}
}
}
Java 7コンパイラは、リスローのメソッドでは、catchブロックが例外をキャッチしているが、throws句の一部ではないことが分かります。Java 7コンパイラは、tryブロック全体を分析して、どのタイプの例外がスローされ、その後にcatchブロックからリスローされるかを確認します。ただし、catchブロックの引数を変更すると、この分析は無効になります。詳しくは「Javaにおける例外処理」をお読みください。