Yomiage
メニュー

Java実践講座 08:例外・Optional・リソース管理

更新 2026/9/27 6:22:11 公開

投稿者: しゅりりん

到達点は、失敗の種類を分け、後始末を確実にすることです。前提は第07回です。

失敗を成功に見せない

「検索結果がない」「文字列を数値にできない」「ファイルを読めない」は違う状態です。通常の不在ならOptional、呼び出し規約の違反やI/O失敗なら例外が候補になります。例外を捕まえて空の結果を返すだけだと、障害と正常な0件を区別できなくなります。

import java.io.*;
import java.util.OptionalInt;

public class Main {
    static OptionalInt parseMinutes(String text) {
        try {
            int value = Integer.parseInt(text.strip());
            return value >= 0 ? OptionalInt.of(value) : OptionalInt.empty();
        } catch (NumberFormatException e) {
            return OptionalInt.empty();
        }
    }

    public static void main(String[] args) throws IOException {
        try (BufferedReader reader = new BufferedReader(new StringReader("25\nabc\n"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                OptionalInt result = parseMinutes(line);
                System.out.println(result.isPresent() ? result.getAsInt() : "入力が不正");
            }
        }
    }
}

Main.javaで実行すると25と「入力が不正」が出ます。このメソッドでは負の数と数値でない入力を、どちらも「変換できない」という一種類にまとめる契約にしました。理由を画面へ細かく返す必要があるなら、別の結果型を設計します。nullを受け付ける契約にはしていません。

捕まえる場所と閉じる場所

checked exceptionは呼び出し側に処理またはthrows宣言を要求します。RuntimeExceptionの派生はその要求を受けません。ただし、チェックされるかどうかと、無視してよいかどうかは別問題です。

try-with-resourcesはAutoCloseableな資源をスコープ終了時に閉じます。ファイル、データベース接続などに有効です。例外で途中終了しても後始末されます。エラーを別の例外へ変換するときは、元の例外をcauseとして渡し、原因を追えるようにします。

Optionalのgetを無条件に呼べば、不在時に失敗します。orElse は代替値を先に評価し、orElseGet は必要時に計算します。重い代替処理には違いが出ます。

練習と解答

練習:「0」「-1」「abc」「 12 」を分類し、ファイルの読み取り失敗を同じ「入力が不正」にしてよいか考えます。

解答:0と12は有効、残りは不正です。読み取り失敗まで同じにすると、利用者は入力を直しても解決できません。外側でI/O失敗を扱い、再試行や終了を判断します。

公式資料

例外とOptional APIを参照できます。


Java全20回の目次 | 前の回 | 次の回

このブラウザでは Web Speech API が利用できません。

1 / 16 · 停止中