コース一覧
    Java中級:例外処理とファイル入出力
    複数の catch ブロック

    Java中級:例外処理とファイル入出力

    例外処理とファイル入出力を学び、失敗に対応しながらデータを読み書きするプログラムを作れるようにします。

    1
    例外処理
    01. try-catch で例外をつかむ5分
    02. 複数の catch ブロック5分
    03. throws と例外の伝播5分
    04. 独自の例外を作る5分
    05. try-with-resources5分
    06. finally ブロック5分
    07. 例外処理 まとめクイズ5分
    2
    ファイル I/O
    01. Files でファイルに書き込む5分
    02. ファイルを行単位で読む5分
    03. Path でファイルパスを扱う5分
    04. BufferedReader と Stream API5分
    05. ファイルの存在確認と削除5分
    06. ファイル I/O まとめクイズ5分

    複数の catch ブロック

    「エラーが出ました」だけでは、直しようがない

    在庫数から「1 人あたり何個配れるか」を出す処理を考えます。ここで失敗する理由は 2 つあります。指定された商品番号が存在しないか、在庫が 0 で割り算ができないかです。

    Java

    try {
        System.out.println(names[i] + " は 1 人あたり " + (100 / stock[i]) + " 個");
    } catch (Exception e) {
        System.out.println("エラーが出ました");
    }

    これでも落ちはしません。ただ、画面に出るのは毎回「エラーが出ました」だけです。使う人は、番号を打ち直せばいいのか、在庫を補充すればいいのかが分かりません。例外を捕まえる目的は、落とさないことだけではなく、何が起きたのかを正しく区別して伝えることにあります。

    catch は縦に並べられる

    1 つの try に対して、catch は何個でも並べられます。投げられた例外の型に当てはまる最初の catch が実行されます。

    Java

    try {
        System.out.println(names[i] + " は 1 人あたり " + (100 / stock[i]) + " 個");
    } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("その番号の商品はありません");
    } catch (ArithmeticException e) {
        System.out.println("在庫が 0 なので計算できません");
    }

    これで、番号が範囲外なら前者、在庫が 0 なら後者のメッセージが出ます。原因ごとに違う手当てができるようになりました。

    並べる順番には決まりがあります。狭い型を先、広い型をあとに書きます。catch (Exception e) を先頭に置くと、その下の catch には二度と処理が届かないので、コンパイラが exception has already been caught と言って止めてくれます。

    手当てが同じなのに、同じコードを 2 回書きたくない

    原因が違っても、やることが同じ場合があります。「どちらの失敗でも、その行を飛ばしてログに残すだけ」といったケースです。このときは | で例外型を並べて 1 つの catch にまとめられます。

    Java

    try {
        importRow(row);
    } catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {
        System.out.println("この行は飛ばします " + e.getMessage());
    }

    この書き方の中では、e は並べた型の共通の親として扱われます。ここでは RuntimeException なので、getMessage() のような共通のメソッドは呼べますが、どちらか一方にしかないメソッドは呼べません。

    | で並べられるのは、親子関係にない型どうしだけです。catch (IOException | FileNotFoundException e) は、後者が前者の子なのでコンパイルエラーになります。

    よくある間違い

    「とりあえず広い網を張っておこう」と catch (Exception e) を先頭に書いてしまうのが定番のつまずきです。エラーメッセージだけ見ても意味が分かりにくいので、catch が並んでいるコードで急にビルドが通らなくなったら、まず順番を疑ってください。

    もう 1 つ、戻り値や処理内容が違うのに | でまとめてしまうのも避けたいところです。まとめるのは手当てが同じときだけ、と決めておくと迷いません。

    要件

    1. クラス名は Solution、メソッド名は safeDivide、引数は String a, String b、戻り値の型は int
    2. try の中で Integer.parseInt を 2 回呼んでから割り算を行い、NumberFormatException を捕まえる catch で -1 を返すこと
    3. もう 1 つの catch で ArithmeticException を捕まえて -2 を返すこと。Exception でひと括りにせず、種類ごとに別々の catch で書き分けること

    ヒント

    `Integer.parseInt("abc")` を呼ぶと `NumberFormatException` が投げられます。`try` の中で `int x = Integer.parseInt(a);` のように書きましょう

    整数同士の割り算で割る数が `0` だと `ArithmeticException` が発生します。`catch (ArithmeticException e)` で受け取って `-2` を返します

    `catch` の順序は具体 → 抽象が原則ですが、今回の 2 つはどちらも `RuntimeException` の直接の子クラスなので、`NumberFormatException` → `ArithmeticException` の順で並べれば OK です

    生田 陸人
    監修生田 陸人
    ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
    編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

    関連レッスン

    • throws と例外の伝播

      `throws` キーワードと検査例外の伝播を学び、`Integer.parseInt` の失敗を `try-catch` で受け止めて 0 を返す `safeParse` メソッドを実装してみよう。

    • 独自の例外を作る

      Java の例外クラスを継承して独自の `InsufficientFundsException` を作り、銀行口座の出金処理で `throw` / `catch` する流れを学んでみよう。

    • try-with-resources

      AutoCloseable なリソースを安全に扱う try-with-resources 構文を学び、リソースの自動クローズを体験しよう。

    • finally ブロック

      Java の `try` 文で必ず実行される `finally` ブロックの役割をリソース解放や後始末の観点から学び、整数除算の結果を `,end` 付きで返すメソッドを実装してみよう。

    このレッスンに出てくる用語

    意味があいまいなまま進んだ語は、ここから読み直せます。

    • 処理計算や代入を表す長方形
    • メソッドクラスに属する関数
    • コンパイルソースをバイトコードへ変換する処理
    • エラーメッセージプログラムが出す失敗の通知
    • 戻り値呼び出し元への返答を表す点線矢印
    • クラスデータと振る舞いを束ねる単位
    • 引数位置引数=順番で渡す。
    main.java
    エディタを読み込んでいます

    メモ

    複数の catch ブロック

    ⌘S で保存