注目記事

【Javaコード入門】例外処理_④throw命令

例外をスローする – throw命令

throw exclazz
 exclazz:例外オブジェクト

例外はキャッチ(捕捉)するばかりでなく、自分で投げることもできます(これを「例外をスローする」と言います)。メソッドの中で例外をスローする際には、メソッド定義でもthrows句(複数形)で発生する可能性のある例外を明示しなければなりません。複数の例外を発生する可能性がある場合には、例外をカンマ区切りで列記します

  1. public void sample() throws HogeException {
  2.  throw new HogeException();
  3. }

上のようなsampleメソッドを呼び出すには、これまでと同じくtry句による例外の処理が必須です。

  1. try {
  2.  var t = new TrySample();
  3.  t.sample();
  4. } catch (HogeException e) {
  5.  e.printStackTrace();
  6. }

例外の選択

自ら例外をスローする場合には、以下の点にも注意してください。

(1)適切な例外を選択する

特に、検査例外/非検査例外いずれをスローするかを決めることは大切です。なぜなら、検査例外をスローするということは、利用者側にも例外処理を強制するということだからです。つまり、例外をキャッチしてもそのままログを吐き出し、アプリを終了するしかないのであれば、例外を強制する意味はないということです(非検査例外で十分です)。

(2)標準的な例外をできるだけ利用する

アプリでもExceptionクラス、またはその派生クラスを継承することで、独自の例外クラスを定義することは可能です。しかし、Javaでは標準でよく利用する例外をさまざまに提供しており、これらは一般的な開発者にとって見慣れたものです。まずは、標準の例外を利用することで、例外の意味も把握しやすく、コードの可読性が向上します。
以下は、よく利用する例外です。

Javaの主な例外クラス
例外 概要
NullPointerException オブジェクトがnullである
IndexOutOfBoundsException インデックスが範囲外
UnsupportedOperationException 要求された操作が未サポート
IllegalArgumentException メソッドに渡されたパラメーターが不正である
ArithmeticException 計算で例外的な条件が発生

 

assert命令
メソッドに不正な引数を渡した場合には、IllegalArgumentyException例外で呼び出し元に通知するのが定石です。しかし、protected/privateメソッドのように内部的に利用するメソッドで、引数の内容も保証される場合には、assert命令を利用することをお勧めします。

 

  1. protected double getCircle(double radius) {
  2.  assert radius > 0;
  3.  return radius * radius * Math.PI;
  4. }

assertメソッドはjavaコマンドで-eaオプションを付与した場合にだけ実行される命令で、与えられた式がfalseの場合に、AssertionError例外を発生します。
信頼性の高い文脈では、assert命令を利用することで、if/throw命令を除去できますので、コードの見通しが良くなります。

(3)Exceptionをスローしない

catchブロックの説明でも触れたように、Exceptionはすべての例外のスーパークラスで、「一般的な例外」という以上の情報を持ちません。例外の型だけで、ある程度例外の種類が識別できるよう、スローするのはExceptionクラスの個別の派生クラスとするべきです。

例外の再スロー

catchブロックの中で、受け取った例外を再スローすることも可能です。

  1. try {
  2.  reader = new FileReader("C:/data.txt");
  3. } catch (FileNotFoundException e) {
  4.  throw e;
  5. }

補足した例外を自分で処理できない場合には、まずは呼び出し元に再スローするようにしてください。catchブロックを空にするなどしてしまうと、そもそも例外が発生したこと自体を確認できなくなってしまうので、絶対に避けるようにしてください。

例外処理_目次
例外処理
try…catch命令
finally句
throw命令

監修

山田祥寛(有限会社 WINGSプロジェクト)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NEC にてシステム企画業務に携わるが、2003年 4 月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト(https://wings.msn.to/)」の代表でもある。主な著書に『改訂 3 版JavaScript 本格入門』(技術評論社)、「独習シリーズ(C#・Python・PHP・Ruby・JSP&サーブレットなど)」(翔泳社)、「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravel など)」(Amazon Kindle)など。売り上げの累計は100万部を超える。