You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java ATM模拟程序抛出IllegalStateException异常,求原因及修复方案

嘿,我来帮你拆解这个问题,一步步解决你的ATM程序异常问题:

问题分析与解决方案

1. 什么是IllegalStateException?

简单说,这是一种运行时异常,当你调用某个对象的方法,但这个对象当前的状态根本不允许执行这个操作时,就会抛出它。比如你现在的情况:Scanner已经被关闭了,你还想调用它的nextInt()方法读取输入,这就属于“对象状态不合法”,所以触发了这个异常。

2. 你的场景里异常产生的核心原因

看你的代码,问题出在finally块的位置:
你把input.close();放在了最内层的try-catch的finally里,而这个try-catch又嵌套在外层的do-while循环中。

  • 第一次用户输入非数字触发InputMismatchException时,catch块处理完异常,finally会强制执行,直接把Scanner关闭了。
  • 但外层的do-while循环还在继续跑,下一次循环再调用input.nextInt()的时候,Scanner已经是关闭状态了,自然就抛出了IllegalStateException。

另外还有个隐藏问题:触发InputMismatchException后,用户输入的无效内容(比如字母)还留在Scanner的输入缓冲区里,如果不清理,下次循环会一直读取这个无效内容,导致无限抛出异常。

3. 具体修复步骤

(1)把Scanner关闭移到循环外面

Scanner是整个程序用来读取输入的工具,应该等到整个程序结束(也就是外层循环退出后)再关闭,而不是每次循环结束就关闭。把input.close();从finally块里移到最外层do-while循环的外面。

(2)在catch块里清理输入缓冲区

捕获InputMismatchException后,调用input.nextLine()把缓冲区里的无效输入清空,这样下次循环才能正常读取新的用户输入。

修改后的核心代码示例

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    boolean infiniteLoop = true;
    boolean invalidInput;
    int id;

    Account[] accountArray = new Account[10];
    for (int i = 0; i < accountArray.length; i++) {
        accountArray[i] = new Account(i, 100);
    }

    do {
        try {
            // 原有的内部ID验证循环
            do {
                invalidInput = false;
                System.out.print("Enter an id: ");
                id = input.nextInt();
                if (id < 0 || id > 9) {
                    System.out.println("Try again. Id not registered in system. Please enter an id between 0 and 9 (inclusive).");
                    invalidInput = true;
                    input.nextLine();
                }
            } while (invalidInput);

            // 原有的主菜单循环
            boolean exit;
            do {
                exit = false;
                boolean notAnOption;
                int choice;
                do {
                    notAnOption = false;
                    System.out.print("\nMain Menu\n1: check balance\n2: withdraw\n3: deposit\n4: exit\nEnter a choice: ");
                    choice = input.nextInt();
                    if (choice < 1 || choice > 4) {
                        System.out.println("Sorry, " + choice + " is not an option. Please try again and enter a number between 1 and 4 (inclusive).");
                        notAnOption = true;
                    }
                } while(notAnOption);

                switch (choice) {
                    case 1:
                        System.out.println("The balance for your account is $" + accountArray[id].getBalance());
                        break;
                    case 2:
                        boolean withdrawFlag;
                        do {
                            System.out.print("Enter the amount you would like to withdraw: ");
                            // 建议改成nextDouble支持小数金额
                            double withdrawAmount = input.nextDouble();
                            if (withdrawAmount > accountArray[id].getBalance()) {
                                System.out.println("Sorry, you only have an account balance of $" + accountArray[id].getBalance() + ". Please try again and enter a number at or below this amount.");
                                withdrawFlag = true;
                            } else {
                                accountArray[id].withdraw(withdrawAmount);
                                System.out.println("Thank you. Your withdraw has been completed.");
                                withdrawFlag = false;
                            }
                        } while (withdrawFlag);
                        break;
                    case 3:
                        System.out.print("Enter the amount you would like to deposit: ");
                        // 建议改成nextDouble支持小数金额
                        double depositAmount = input.nextDouble();
                        accountArray[id].deposit(depositAmount);
                        System.out.println("Thank you. You have successfully deposited $" + depositAmount + " into your account.");
                        break;
                    case 4:
                        System.out.println("returning to the login screen...\n");
                        exit = true;
                        break;
                }
            } while (!exit);

        } catch (InputMismatchException ex) {
            System.out.println("Sorry, invalid input. Please enter a number, no letters or symbols.");
            // 清理缓冲区的无效输入
            input.nextLine();
        }
        // 移除原来的finally块
    } while (infiniteLoop);

    // 程序结束前才关闭Scanner
    input.close();
}

额外优化建议

  • 你的infiniteLoop变量一直是true,程序会无限运行,建议可以加个退出逻辑,比如在ID输入环节输入-1时,把infiniteLoop设为false,让程序正常退出。
  • 目前你用input.nextInt()处理存款和取款金额,只能接受整数,改成input.nextDouble()可以支持小数金额,更符合ATM的实际场景。

内容的提问来源于stack exchange,提问作者Ryan Foster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:28:29