例外処理におけるthrowsキーワードの適切な使い分けと設計判断

こんにちは。ゆうせいです。

新人研修中に受講者から以下の質問をいただきました。

例外のthrowsキーワードをメソッドにつけるべきかどうかはどうやって判断したら良いですか?

今回はこの質問に答えたいと思います。

Javaにおける例外処理は、プログラム実行中に発生した予期せぬ事態にどう対処するかを定義する仕組みです。その中でthrowsキーワードは、発生した例外の処理を自分で行わず、呼び出し元のメソッドへ転送することを宣言するために使用されます。このキーワードを付与すべきかどうかの判断基準について、例外の種類と設計上の役割の観点から解説します。

例外の分類とthrowsの関係

Javaの例外は、大きく分けてチェック例外と非チェック例外の2種類に分類されます。throwsキーワードの要否は、まずこの分類によって決まります。

チェック例外(検査例外)

ファイル操作やネットワーク通信など、プログラムの外部要因によって発生する可能性がある例外です。Javaコンパイラによって処理が強制されるため、メソッド内でtry-catchを用いて処理するか、throwsを用いて外部へ通知するかの選択が必須となります。

比喩を用いるなら、チェック例外は海外旅行におけるパスポートの所持確認のようなものです。空港のカウンター(メソッド)でパスポートを忘れたことが判明した際、その場で家族に届けてもらう(try-catch)か、さらに上位の責任者へ判断を仰ぐ(throws)かを選択しなければ、飛行機には乗れません。

非チェック例外(非検査例外)

数値のゼロ除算や、null参照へのアクセスなど、主にプログラミング上のミスによって発生する例外です。これらはthrowsに記述しなくても文法上のエラーにはなりませんが、必要に応じて記述することも可能です。

比喩を用いるなら、これは歩行中に靴紐が解けるような事態です。注意していれば防げることであり、わざわざ契約書(メソッドの定義)に靴紐が解ける可能性を明記することは通常ありません。

throwsを付与すべきかどうかの判断基準

メソッドにthrowsを付与するかどうかの判断は、そのメソッドが例外に対して責任を持てるかどうかという事実に基づきます。

呼び出し元に判断を委ねるべきケース

メソッドが単一の機能を提供する部品に徹している場合、例外処理を自分で行わずにthrowsを使用するのが適切です。

  • 事実:メソッド内部では、発生した問題に対してどうリカバーすべきか(ユーザーに通知するのか、リトライするのか)の文脈を知り得ない。
  • メリット:メソッドの再利用性が高まり、呼び出し側で状況に応じた柔軟な対応が可能になる。

自身のメソッドで完結させるべきケース

そのメソッドの役割が、特定の処理を確実に遂行することであり、例外が発生しても代替手段を提供できる場合は、try-catchを使用して内部で解決します。

  • 事実:例外を外に投げると、呼び出し元のコードが複雑になり、利用者に負担を強いることになる。
  • デメリット:不適切にthrowsを多用すると、上位のメソッドが大量の例外宣言に埋もれ、保守性が著しく低下する。

throws使用時のメリットとデメリット

設計判断を誤った際の影響を整理します。

メリット

  • 例外が発生する可能性があることをメソッドの利用者に明示できる。
  • 正常な処理の流れと、異常時の処理の流れを分離して記述できる。
  • 下位層で発生した詳細なエラー情報を、適切な処理が可能な上位層まで劣化させずに届けることができる。

デメリット

  • 呼び出し側のすべての箇所で例外処理の記述が強制される。
  • 内部実装の都合(特定のライブラリが投げる例外など)がメソッドの定義に漏れ出し、カプセル化が損なわれる可能性がある。
  • 処理を丸投げし続けることで、最終的なmainメソッドまで例外が到達し、プログラムが不親切な形で強制終了する原因となる。

学習のステップ

例外設計を習得するために、以下の順序で学習を進めてください。

  1. ExceptionクラスとRuntimeExceptionクラスの継承関係を整理し、チェックの有無による挙動の違いを確認する。
  2. 自分で定義した独自の例外クラス(カスタム例外)を作成し、適切な階層でthrowsを宣言する練習を行う。
  3. インターフェースの設計において、実装クラスが投げる可能性のある例外をどこまで抽象化してthrowsに含めるべきかを検討する。
  4. 標準ライブラリのAPIリファレンスを読み、どのようなメソッドがどのような理由で例外を投げているかのパターンを分析する。

throwsキーワードは責任の転送を意味します。自分が処理すべき責任なのか、呼び出し側に通知すべき情報なのかを見極めることが、堅牢なプログラムへの第一歩です。

グループでは新人エンジニア研修のアシスタント講師を募集しています。

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。

学生時代は趣味と実益を兼ねてリゾートバイトにいそしむ。長野県白馬村に始まり、志賀高原でのスキーインストラクター、沖縄石垣島、北海道トマム。高じてオーストラリアのゴールドコーストでツアーガイドなど。現在は野菜作りにはまっている。