throwsを用いるかどうかはメソッドの役割で決まるJavaTips 〜Javaプログラミング編

» 2006年11月22日 10時00分 公開
[平野正喜@IT]

 例外が発生する可能性があるメソッドでは、そのメソッドにおいて例外を捕捉するか、そのメソッドを呼び出したメソッドに例外を投げる(任せる)かを選ぶ必要があります(例外がRuntimeExceptionのサブクラスである場合を除く)。前者を選ぶ場合は「try-catch」構文を用い、後者を選ぶ場合は「throws」を用います。

 このどちらを選択するかは、機械的には決められません。メソッドの役割を考えて選択する必要があります。また、複数の例外がある場合、「try-catch」すべき例外と「throws」すべき例外に分けることを考えましょう。

 まず、コンパイルエラーを逃れるためだけの「throws」は避けるべきです。下は最も悪い例といえるでしょう。

コンパイルエラーを逃れるためだけの「throws Exception」の悪例 コンパイルエラーを逃れるためだけの「throws Exception」の悪例

 6行目の「throws Exception」を外すと分かりますが、このメソッドは、URLクラスのコンストラクタが不正なURLを受け取ったときに投げる MalformedURLException と、openConnectionメソッドが投げる IOException を「try-catch」または「throws」する必要があります。この2つの例外を、まとめて単純に投げているわけですから、このメソッドを呼び出す側に、例外への対応を押し付けているにすぎません。

 また、このメソッドに機能を追加して、対処すべき例外が増えた場合、対処しなくてもコンパイルエラーにならないため、本来必要な措置をし忘れる懸念があります。

「try-catch」すべき例外と「throws」すべき例外に分ける

 この例を用いて「try-catch」するか、「throws」するかを検討した結果が以下です。

呼出側で処理すべき例外のみ「throws」するように改良 呼出側で処理すべき例外のみ「throws」するように改良

 単純に「throws Exception」を「throws MalformedURLException, IOException」にしても解決しますが、「try-catch」すべき例外と「throws」すべき例外に分けることを考えましょう。この例では、受け取ったURLに問題がある場合に、MalformedURLException が発生します。よって、この例外の責任は呼び出した側にありますので、対処も呼び出した側で行うべきでしょう。よって、「throws MalformedURLException」としました。

 これに対して、IOException は、呼び出し側とは無関係に、このメソッドの内部で投げられる例外です。よって「try-catch」しました。

 この例で示した使い分けは、あくまでも一例にすぎませんが、メソッドの役割を考え「try-catch」すべき例外と「throws」すべき例外に分けることは、プログラムを見やすくし、トラブルの防止に役立ちます。

Profile

RunDog.org

平野正喜


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。