Menu
CoddyTech

异常处理集成

本课属于 Coddy Java 学习旅程的“面向对象编程”单元。第 82 课,共 87 课。

challenge icon

挑战

简单

通过集成恰当的异常处理,让你的图书管理系统更加健壮!真实的图书馆系统需要妥善处理错误情况:有人试图借阅一本不存在的书时会怎样?用户试图借阅超过规定数量的书时又会怎样?你将创建自定义异常,为这些情况提供有用的反馈。

你将继续在 6 个文件中完善现有代码:

  • Book.java:保留你的 Book 类及其所有现有功能:isbn、title、author、isAvailable、borrowedBy、getDetails(),以及相应的 getter 和 setter。
  • User.java:保留你的 User 类,其中包含 id、name、borrowedBooks ArrayList、borrowBook()、returnBook()、getBorrowedCount() 和 toString()。
  • LibraryException.java:创建一个名为 LibraryException 的自定义基础异常类,使其继承 Exception。它将作为所有图书馆专用异常的父类。添加一个接收消息并将其传递给父类的构造函数。
  • BookNotAvailableException.java:创建一个继承 LibraryException 的自定义异常。当有人试图借阅一本已经被借出的书时,应抛出此异常。添加一个接收图书 ISBN 并创建有意义消息的构造函数,例如 Book not available: [isbn]。
  • Library.java:更新你的 Library 类,让它抛出异常,而不是打印错误消息。修改 borrowBook(String userId, String isbn) 方法,使其:
    • 如果用户不存在,则抛出消息为 User not found: [userId] 的 LibraryException
    • 如果图书不存在,则抛出消息为 Book not found: [isbn] 的 LibraryException
    • 如果图书已经被借出,则抛出 BookNotAvailableException
    • 如果操作成功,则让用户借阅图书,并返回确认消息 [userName] borrowed [bookTitle]

    将方法签名改为 throws LibraryException,并将返回类型改为 String。

    保留其他所有方法(addBook、registerUser、findBookByIsbn、findUserById、returnBook、removeBook、searchByTitle、searchByAuthor、getAvailableBooks),让它们继续像之前一样工作。

  • Main.java:展示你的异常处理!你将收到一个以逗号分隔的命令字符串。每条命令都符合以下格式之一:
    • ADD_BOOK:isbn:title:author
    • REGISTER_USER:id:name
    • BORROW:userId:isbn

    处理每条命令。对于 ADD_BOOK,打印 Added: [title]。对于 REGISTER_USER,打印 Registered: [name]。对于 BORROW 命令,使用 try-catch 块处理异常;如果操作成功,则打印确认消息;如果发生任何 LibraryException,则打印 Error: [exception message]。

    处理完所有命令后,打印 Operations completed。

你将收到一个输入:以逗号分隔的命令字符串。

例如,输入为 ADD_BOOK:ISBN-001:Clean Code:Robert Martin,REGISTER_USER:U001:Alice,BORROW:U001:ISBN-001,BORROW:U001:ISBN-001,BORROW:U002:ISBN-001 时,输出为:

Added: Clean Code
Registered: Alice
Alice borrowed Clean Code
Error: Book not available: ISBN-001
Error: User not found: U002
Operations completed

注意,自定义异常提供了清晰、具体的错误消息。第一次借阅成功,第二次因为图书已经被借出而失败(BookNotAvailableException),第三次则因为用户 U002 不存在而失败(LibraryException)。与通用错误消息相比,这种做法能让你的图书馆系统提供更多信息,也更容易调试!

亲手试试

import java.util.Scanner;
import java.util.ArrayList;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 读取以逗号分隔的命令
        String input = scanner.nextLine();
        String[] commands = input.split(",");
        
        // 创建 Library 和 AdminService
        Library library = new Library();
        AdminService adminService = new AdminService(library);
        
        // 处理每条命令
        for (String command : commands) {
            String[] parts = command.split(":");
            String operation = parts[0];
            
            if (operation.equals("ADD_BOOK")) {
                String isbn = parts[1];
                String title = parts[2];
                String author = parts[3];
                if (adminService.addBook(isbn, title, author)) {
                    System.out.println("Added: " + title);
                }
            } else if (operation.equals("REMOVE_BOOK")) {
                String isbn = parts[1];
                if (adminService.removeBook(isbn)) {
                    System.out.println("Removed: " + isbn);
                } else {
                    System.out.println("Cannot remove: " + isbn);
                }
            } else if (operation.equals("REGISTER_USER")) {
                String id = parts[1];
                String name = parts[2];
                if (adminService.registerUser(id, name)) {
                    System.out.println("Registered: " + name);
                }
            } else if (operation.equals("BORROW")) {
                String userId = parts[1];
                String isbn = parts[2];
                // TODO: 使用 try-catch 块调用 library.borrowBook(userId, isbn)
                // 成功时,打印返回的确认消息
                // 发生 LibraryException 时,打印 "Error: " + e.getMessage()
            }
        }
        
        // TODO: 打印 "Operations completed"
    }
}

面向对象编程中的所有课

自己练习: Java 在线编译器