3

多くの場合、テンプレート メソッドまたはインターフェイス メソッドを実装する場合、メソッドによって定義された特定の種類の例外を 1 つしかスローできません。ただし、実装によって、互換性のない例外タイプまたは多くの異なる例外タイプをスローする API へのクラスが作成される場合があります。

当然、それらをキャッチし、実装されたメソッド シグネチャに適した型に例外をラップする必要があります。このインターフェースを実装したいとしましょう:

public interface SomeDataGetter {

    public long getSomeData() throws IOException;

}

私たちの実装は、これを実装するために他の API 製品を利用しており、呼び出している API メソッドには次の署名がある場合があります。

public long loadFromDBOrCache(Object ... params) throws SQLException, IOException, ObjectNotFoundException, RuntimeException, FridayException, NotWeekendException, NumberIs42Exception;

スローされる可能性のあるすべての例外を具体的な型で正確に列挙できない場合を示すために、これを作成しました。IOException は、実装からスローできる型であることに注意してください。

これを実装するときに怠惰なルートに進み、署名に合うように何かをラップできます。

@Override
public long getSomeData() throws IOException {
    try {
        return loadFromDB(...);
    } catch (Exception e) {
        throw new IOException(e.getMessage(), e);
    }
}

これは明らかに例外を IOException (IOException であっても) にラップし、問題なく動作しますしかし、ラップせずにスローすることが許可されているため、IOExceptions をラップしたくありません。

@Override
public long getSomeData() throws IOException {
    try {
        return loadFromDB(...);
    } catch (IOException e) {
        throw e;
    } catch (Exception e) {
        throw new IOException(e.getMessage(), e);
    }
}

実装に複数の可能性のある例外があり、実装から許可されている複数の例外がある場合、これはすぐに面倒になると想像できます。通過させたい例外ごとに追加のキャッチが必要です。

それを読みやすく保ち(また、私は怠け者で、これらすべての余分なキャッチを書きたくない)、不要な例外のネストを回避するための最良のイディオムは何ですか? それとも、気にせずにすべてをラップする必要がありますか?

4

2 に答える 2