例外が発生する可能性があるメソッドでは、そのメソッドにおいて例外を捕捉するか、そのメソッドを呼び出したメソッドに例外を投げる(任せる)かを選ぶ必要があります(例外がRuntimeExceptionのサブクラスである場合を除く)。前者を選ぶ場合は「try-catch」構文を用い、後者を選ぶ場合は「throws」を用います。
このどちらを選択するかは、機械的には決められません。メソッドの役割を考えて選択する必要があります。また、複数の例外がある場合、「try-catch」すべき例外と「throws」すべき例外に分けることを考えましょう。
まず、コンパイルエラーを逃れるためだけの「throws」は避けるべきです。下は最も悪い例といえるでしょう。
6行目の「throws Exception」を外すと分かりますが、このメソッドは、URLクラスのコンストラクタが不正なURLを受け取ったときに投げる MalformedURLException と、openConnectionメソッドが投げる IOException を「try-catch」または「throws」する必要があります。この2つの例外を、まとめて単純に投げているわけですから、このメソッドを呼び出す側に、例外への対応を押し付けているにすぎません。
また、このメソッドに機能を追加して、対処すべき例外が増えた場合、対処しなくてもコンパイルエラーにならないため、本来必要な措置をし忘れる懸念があります。
「try-catch」すべき例外と「throws」すべき例外に分ける
この例を用いて「try-catch」するか、「throws」するかを検討した結果が以下です。
単純に「throws Exception」を「throws MalformedURLException, IOException」にしても解決しますが、「try-catch」すべき例外と「throws」すべき例外に分けることを考えましょう。この例では、受け取ったURLに問題がある場合に、MalformedURLException が発生します。よって、この例外の責任は呼び出した側にありますので、対処も呼び出した側で行うべきでしょう。よって、「throws MalformedURLException」としました。
これに対して、IOException は、呼び出し側とは無関係に、このメソッドの内部で投げられる例外です。よって「try-catch」しました。
この例で示した使い分けは、あくまでも一例にすぎませんが、メソッドの役割を考え「try-catch」すべき例外と「throws」すべき例外に分けることは、プログラムを見やすくし、トラブルの防止に役立ちます。
Copyright © ITmedia, Inc. All Rights Reserved.