Java | 1 日 90 分 × 7 日アプリ学習 初級編:例外処理アプリ

Web APP Java
スポンサーリンク

1日目のゴール

1日目のテーマは
「例外ってそもそも何?」「try / catch って何をしているの?」を、感覚でつかむこと です。

今日は、こんな流れで進めます。

例外とは何か
なぜ try / catch が必要なのか
超シンプルな「割り算アプリ」で例外を体験する
異常系(うまくいかないケース)を“想定して書く”感覚を持つ


例外ってそもそも何者?

「普通じゃないことが起きた」ときの合図

Java でプログラムを書いていると、
「普通に進められない状況」が必ず出てきます。

存在しないファイルを開こうとした
0 で割り算しようとした
数字じゃない文字列を、整数に変換しようとした

こういうとき、Java は
「例外(Exception)」という“特別な出来事”を投げてきます。

「もうこのままは続けられないから、誰かこの状況を処理して!」
という“ヘルプの叫び”みたいなものです。

エラーと例外のざっくり違い

初心者のうちは、こう覚えておけばOKです。

コンパイルエラー
→ そもそも文法が間違っていて、プログラムが“始まる前に”止まる

例外(Exception)
→ 文法は正しいけど、“実行中に”問題が起きて止まる可能性があるもの

今日扱うのは、後者の「実行中のトラブル」です。


try / catch の役割を一言でいうと

「ここで失敗するかも」を囲っておく

try / catch は、ざっくり言うとこうです。

この中の処理は、失敗するかもしれない(try)
もし失敗したら、ここで受け止めてどうするか決める(catch)

形はこう。

try {
    // 失敗するかもしれない処理
} catch (Exceptionの種類 e) {
    // 失敗したときにやりたい処理
}
Java

ポイントは二つです。

「どこが失敗するか」を自分で囲む
「失敗したときにどう振る舞うか」を自分で決める

これが「異常系対策」です。


例題:割り算ミニアプリで例外を体験する

作るもののイメージ

コンソールで動く、超シンプルな割り算アプリを作ります。

1つ目の数を入力
2つ目の数を入力
割り算して結果を表示

ここで、わざと「失敗しそうなケース」を考えます。

数字じゃない文字を入力したら?
0 で割ったら?

これを、try / catch で受け止めていきます。

まずは「例外なし」で書いてみる

import java.util.Scanner;

public class DivideApp {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("1つ目の整数を入力してください: ");
        String aStr = scanner.nextLine();

        System.out.print("2つ目の整数を入力してください: ");
        String bStr = scanner.nextLine();

        int a = Integer.parseInt(aStr);
        int b = Integer.parseInt(bStr);

        int result = a / b;
        System.out.println("結果: " + result);

        scanner.close();
    }
}
Java

一見、普通に見えますが、
このコードには“爆弾”が二つ埋まっています。

数字じゃない文字を入れると Integer.parseInt で例外
2つ目に 0 を入れると a / b で例外

実行して、わざとやってみると、
赤いエラーメッセージが出てプログラムが落ちます。

これが「例外が投げられて、誰も受け止めなかった状態」です。


NumberFormatException を try / catch で受け止める

「数字じゃない入力」を想定する

まずは、Integer.parseInt のところを守ります。

import java.util.Scanner;

public class DivideApp {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("1つ目の整数を入力してください: ");
        String aStr = scanner.nextLine();

        System.out.print("2つ目の整数を入力してください: ");
        String bStr = scanner.nextLine();

        try {
            int a = Integer.parseInt(aStr);
            int b = Integer.parseInt(bStr);

            int result = a / b;
            System.out.println("結果: " + result);
        } catch (NumberFormatException e) {
            System.out.println("整数として解釈できない入力があります。数字だけを入力してください。");
        }

        scanner.close();
    }
}
Java

ここでのポイントを分解します。

try { ... } の中に「失敗しそうな処理」をまとめた
catch (NumberFormatException e) で「数字じゃないとき」を受け止めた
例外が起きても、アプリが“落ちずに”メッセージを出して終われる

この時点で、
「変な入力が来ても、ユーザーにメッセージを返せるアプリ」になっています。


ArithmeticException(0で割った)も受け止める

0 で割ったときの例外

次に、a / b のところです。

2つ目の数に 0 を入れると、
ArithmeticException: / by zero という例外が出ます。

これも try / catch で受け止められます。

複数の例外を別々に扱う

import java.util.Scanner;

public class DivideApp {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("1つ目の整数を入力してください: ");
        String aStr = scanner.nextLine();

        System.out.print("2つ目の整数を入力してください: ");
        String bStr = scanner.nextLine();

        try {
            int a = Integer.parseInt(aStr);
            int b = Integer.parseInt(bStr);

            int result = a / b;
            System.out.println("結果: " + result);
        } catch (NumberFormatException e) {
            System.out.println("整数として解釈できない入力があります。数字だけを入力してください。");
        } catch (ArithmeticException e) {
            System.out.println("0 で割ることはできません。2つ目の数には 0 以外を入力してください。");
        }

        scanner.close();
    }
}
Java

ここでの重要ポイントは二つです。

catch は複数書ける
例外の種類ごとに、メッセージや対応を変えられる

「何が起きたか」に応じて、
ユーザーへの説明を変えられるのが、例外処理の強みです。


どこまで try に含めるか、がすごく大事

try の“範囲”を意識する

初心者がよくやりがちなのが、
「とりあえず全部 try に突っ込む」パターンです。

try {
    // なんでもかんでもここに入れる
} catch (Exception e) {
    // とりあえずエラー
}
Java

これは、
「どこで何が失敗したのか」が分かりにくくなるので、あまり良くありません。

今日の例でいうと、
「どこが失敗しそうか」をちゃんと意識して囲むのが大事です。

Integer.parseInt は NumberFormatException を投げる
a / b は ArithmeticException を投げる

だから、その周辺だけを try に入れる、という考え方です。

例:範囲をもう少し細かくする

慣れてきたら、こんな書き方もできます。

int a;
int b;

try {
    a = Integer.parseInt(aStr);
    b = Integer.parseInt(bStr);
} catch (NumberFormatException e) {
    System.out.println("整数として解釈できない入力があります。数字だけを入力してください。");
    scanner.close();
    return;
}

try {
    int result = a / b;
    System.out.println("結果: " + result);
} catch (ArithmeticException e) {
    System.out.println("0 で割ることはできません。2つ目の数には 0 以外を入力してください。");
}
Java

こうすると、

「数字としておかしい」のと
「0 で割った」のが
コード上もきれいに分かれます。

1日目はここまでやらなくてもOKですが、
「try の範囲は、自分で設計するもの」
という感覚だけ持っておいてください。


finally という“最後に必ず実行される場所”

finally の役割

try / catch には、もうひとつ finally があります。

try {
    // 失敗するかもしれない処理
} catch (Exception e) {
    // 失敗したとき
} finally {
    // 成功しても失敗しても、最後に必ず実行される
}
Java

例えば、ファイルやネットワーク、Scanner などの
「開いたら閉じる必要があるもの」を扱うときに使います。

今回の例だと、scanner.close() を finally に入れるのが典型です。

Scanner scanner = new Scanner(System.in);
try {
    // 入力を使った処理
} catch (Exception e) {
    System.out.println("何かエラーが発生しました: " + e.getMessage());
} finally {
    scanner.close();
}
Java

これで、
途中で例外が起きても、
最後に必ず scanner.close() が呼ばれます。


1日目で絶対に押さえてほしい本質

今日いちばん大事なのは、
「例外は“悪いもの”ではなく、“異常を知らせる仕組み”だ」という感覚 です。

例外が投げられるのは、「想定外の状況が起きた」サイン
try / catch は「そのサインを受け取って、自分でどうするか決める場所」
異常系対策とは、「失敗しそうなところを先に想像して、try / catch で囲むこと」

そして、例題の割り算アプリで体験したように、

数字じゃない入力 → NumberFormatException
0 で割る → ArithmeticException
それぞれに対して、ユーザーに分かりやすいメッセージを返せる

ここまでイメージできたら、
もう「例外=よく分からない赤いエラー」ではなく、
「自分で扱える“出来事”」 になっています。

次のステップでは、
「例外を投げる側」「呼び出し元に伝える側」も含めて、
もう少し深く例外処理を設計していけます。

タイトルとURLをコピーしました