iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
自我挑戰組

Java 程式設計與實作:30 天打造個人記帳系統系列 第 15 篇

Exception Handling 例外處理:避免輸入錯誤讓程式當掉

  • 分享至 

  • xImage
  •  

昨天學習了 Java 的 Inheritance(繼承),開始了解父類別、子類別、extends 和 super。

今天先回到我們的記帳系統,解決一個實際使用時很容易遇到的問題:

如果使用者輸入錯誤,程式會怎麼辦?

例如程式要求輸入消費金額:

請輸入消費金額:

正常應該輸入:

150

但如果不小心輸入:

abc

因為 abc 不是整數,程式就可能直接發生錯誤並停止。

所以今天要學習 Exception Handling(例外處理)。

什麼是 Exception?

Exception 可以理解成:

程式執行過程中發生的「例外狀況」。

例如:

int amount = scanner.nextInt();

這行程式預期使用者輸入整數。

如果輸入:

100

沒有問題。

但如果輸入:

一百

或:

abc

Java 就無法把它當成 int 處理,因此會產生 Exception。

如果沒有處理這個問題,程式就可能直接停止。

try 和 catch

Java 可以使用:

try {
} catch (Exception e) {
}

來處理可能發生的錯誤。

可以先簡單理解成:

try
↓
嘗試執行程式
發生錯誤
↓
catch
↓
處理錯誤

例如:

try {
System.out.print("請輸入金額:");
int amount = scanner.nextInt();
System.out.println("金額:" + amount);
} catch (Exception e) {
System.out.println("輸入錯誤!");
}

如果輸入:

100

結果:

金額:100

如果輸入:

abc

程式不會直接結束,而是顯示:

輸入錯誤!

這就是 Exception Handling 最基本的用途。

今天遇到的 InputMismatchException

其實我們可以寫得更精確一點。

當 nextInt() 收到不是整數的內容時,常見的例外是:

InputMismatchException

所以先加入:

import java.util.InputMismatchException;

接著可以寫:

try {
int amount = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("請輸入正確的數字!");
}

這樣就專門處理「輸入格式不是整數」的問題。

為什麼 catch 後還要 nextLine()?

假設使用者輸入:

abc

發生錯誤之後,這個錯誤的輸入還留在 Scanner 裡。

所以通常需要:

scanner.nextLine();

把這次錯誤輸入清掉。

例如:

catch (InputMismatchException e) {
System.out.println("請輸入正確的數字!");
scanner.nextLine();
}

不然下一次讀取資料時可能又遇到問題。

今天的小實作:保護記帳系統

今天把例外處理加入我們的記帳系統。

import java.util.Scanner;
import java.util.ArrayList;
import java.util.InputMismatchException;
class Expense {
private String item;
private int amount;
private String category;
Expense(String item, int amount, String category) {
this.item = item;
this.amount = amount;
this.category = category;
}
public String getItem() {
return item;
}
public int getAmount() {
return amount;
}
public String getCategory() {
return category;
}
}
public class Main {
static Scanner scanner = new Scanner(System.in);
static ArrayList expenses = new ArrayList<>();
public static void main(String[] args) {
boolean running = true;
while (running) {
showMenu();
try {
System.out.print("請選擇功能:");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1:
addExpense();
break;
case 2:
showExpenses();
break;
case 3:
running = false;
System.out.println("已離開個人記帳系統!");
break;
default:
System.out.println("沒有這個選項!");
}
} catch (InputMismatchException e) {
System.out.println("輸入錯誤,請輸入數字!");
scanner.nextLine();
}
}
scanner.close();
}
public static void showMenu() {
System.out.println();
System.out.println("===== 個人記帳系統 =====");
System.out.println("1. 新增消費");
System.out.println("2. 查看紀錄");
System.out.println("3. 離開");
}
public static void addExpense() {
System.out.println();
System.out.println("===== 新增消費 =====");
System.out.print("請輸入消費項目:");
String item = scanner.nextLine();
try {
System.out.print("請輸入消費金額:");
int amount = scanner.nextInt();
scanner.nextLine();
System.out.print("請輸入消費分類:");
String category = scanner.nextLine();
Expense expense =
new Expense(item, amount, category);
expenses.add(expense);
System.out.println("記帳成功!");
} catch (InputMismatchException e) {
System.out.println("金額輸入錯誤,請輸入數字!");
scanner.nextLine();
}
}
public static void showExpenses() {
System.out.println();
System.out.println("===== 消費紀錄 =====");
if (expenses.size() == 0) {
System.out.println("目前沒有消費紀錄。");
} else {
for (int i = 0; i < expenses.size(); i++) {
Expense expense = expenses.get(i);
System.out.println(
(i + 1) + ". "
+ expense.getItem()
+ "|" + expense.getAmount() + " 元"
+ "|" + expense.getCategory()
);
}
}
}
}

正常輸入的情況

執行程式:

===== 個人記帳系統 =====

  1. 新增消費
  2. 查看紀錄
  3. 離開
    請選擇功能:1

輸入:

===== 新增消費 =====
請輸入消費項目:午餐
請輸入消費金額:120
請輸入消費分類:飲食
記帳成功!

這時候資料就會正常加入。

如果金額輸入錯誤

例如:

請輸入消費項目:午餐
請輸入消費金額:abc

以前程式可能直接出現錯誤並停止。

現在則會顯示:

金額輸入錯誤,請輸入數字!

接著程式還可以繼續回到主選單:

===== 個人記帳系統 =====

  1. 新增消費
  2. 查看紀錄
  3. 離開
    請選擇功能:

這就是今天最重要的改進。

主選單輸入錯誤也能處理

我們也替主選單加上:

try {
int choice = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("輸入錯誤,請輸入數字!");
}

所以如果使用者原本應該輸入:

1
2
3

結果輸入:

hello

程式也不會直接當掉。

而是顯示:

輸入錯誤,請輸入數字!

然後再次顯示選單。

try、catch 怎麼記?

今天最重要的其實只有兩個關鍵字。

try

try {
// 可能發生錯誤的程式
}

可以理解成:

「先試著執行看看。」

catch

catch (InputMismatchException e) {
// 發生錯誤時要做什麼
}

可以理解成:

「如果真的發生這個錯誤,就在這裡處理。」

所以我把它記成:

try
│
├── 沒有錯誤 → 正常執行
│
└── 發生 Exception
↓
catch
↓
處理錯誤

Exception Handling 有什麼用?

今天做完之後,我發現 Exception Handling 不只是考試會出現的 Java 語法。

它其實對實際程式非常重要。

因為我們不能保證使用者每一次都按照要求輸入資料。

例如要求輸入:

消費金額:100

使用者可能輸入:

100元

也可能輸入:

abc

甚至可能按錯鍵。

如果一個輸入錯誤就讓整個程式停止,使用體驗會很差。

所以程式除了「功能可以正常執行」之外,也要考慮:

如果使用者做錯了,程式能不能繼續運作?

這也是今天最大的收穫。

Day 15 學習心得

今天學習了 Java 的 Exception Handling 例外處理,主要認識 try、catch 和 InputMismatchException。

之前寫程式時,我比較在意正常輸入之後能不能得到正確結果,沒有特別想到使用者可能輸入錯誤。實際把錯誤輸入放進記帳系統測試之後,才發現如果沒有例外處理,一個很小的輸入錯誤就可能讓整個程式停止。

加入 try 和 catch 之後,即使使用者輸入錯誤,程式也可以顯示提示並繼續執行。我覺得今天的內容讓記帳系統不只是「可以跑」,而是開始考慮實際使用時可能發生的問題。

目前進行到第 15 天,也正式完成 30 天挑戰的一半。前半段從 Java 基礎語法一路學到 ArrayList、Method 和物件導向,現在也開始加入例外處理,接下來希望可以把這些觀念真正整合成更完整的記帳功能。


上一篇
Inheritance 繼承:建立不同類型的消費紀錄
下一篇
記帳系統實作:加入「總支出統計」功能
系列文
Java 程式設計與實作:30 天打造個人記帳系統 共 19 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言