例外処理

例外の使い方に関するTIPSです。

ExceptionかRuntimeExceptionか


例外を使用する際にExceptionとRuntimeExceptionのどちらを使用するか?
それは一般には、その例外の状況と性質によって違います。
NullPointerExceptionを考えた場合、この例外は常にプログラミングエラーを示すことがわかります。
しかし、IllegalAccessExceptionの場合はどうでしょう?
権限管理で利用する場合、それは論理エラーと考えられますが、reflectionMethod()などのほかの状況では
プログラミングエラーとも考えられます。


しかし結局のところ、ExceptionとRuntimeExceptionのどちらを使用するかは幾分個人的見解によるそうです。
本では、以下のようなガイドラインが記載されています。

  • 例外が常にプログラミングエラーの結果起こる場合は、その例外はRuntimeExceptionを直接継承するものにします。
  • ユーザのデータ入力が適切でなかったことを示す例外の場合は、RuntimeExceptionを使用して逃れることができます。これによりビジネスロジックを持つクラス内でのRuntimeExceptionは宣言なしに伝播できます。しかしながら、利用する側ではこれらの例外に注意をする必要があります。
  • 例外が常にビジネスロジックのエラーの結果起こる場合は、その例外はExcepitonを直接継承するもの都市、必要な場合は例外をフィルタします。

例外の使用し忘れ

必須パラメータをBeanに設定する際に、以下のようなチェックをすることで、より堅牢性の高いコード
となります。

public void setCustomerName(final String customerName) {
  if(customerName == null) {
    throw new NullPointerException();
  }
  if(customerName.length() == 0) {
    throw new IllegalArgumentException();
  }
  this.customerName = customerName;
}

多すぎる例外

public class CreditCardDeclinedException extends Exception {}
public class BillingException extends Exception {}
public class NoReservationException extends Exception {}


上記のように内容のない例外をいくつも作成するのはあまりよろしくありません。
以下のようにすることで同様な結果を得ることできます。
新しい例外クラスを宣言する場合は、その例外が他の例外とは根本的に異なることを確認するようにして下さい。

public class MyException extends Exception {
  public static final int GUI_ERROR = 0;
  public static final int NO_RESERVATION = 1;
  public static final int TRANSACTION_ERROR = 2;
  public static final int BILLING_ERROR = 3;
  public static final int CREDIT_CARD_DECLINED = 4;

  final int type;

  public MyException(final int type) {
    if((type != GUI_ERROR)
      && (type != NO_RESERVATION)
      && (type != TRANSACTION_ERROR)
      && (type != BILLING_ERROR)
      && (type != CREDIT_CARD_DECLINED)) {
      throw new IllegalArgumentException();
    }
    this.type = type;
  }

  public int getType() {
    return this.type;
  }
}


また、以下のようにすることで、例外の宣言をする場合も例外を複数記述する必要がなくなる為、
すっきりします。
(但し、Javadocでどのような内容の例外がthrowされるのかは記載しておく必要があるかな。。)

public void billCard() 
  throws CreditCardDeclinedException, BillingException {
}

↓こうなります。

public void billCard() 
  throws MyException {
}