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

运行Java收银程序时触发ArrayIndexOutOfBoundsException求助

ArrayIndexOutOfBoundsException 异常排查与修复

问题原因

当找零金额是整数(比如5.0元)时,你用的默认DecimalFormat会把它格式化成不带小数点的字符串(例如"5")。调用split("\\.")拆分后,得到的数组只有parts[0]这一个元素,此时强行访问parts[1]自然会触发数组越界异常。

另外还有个隐藏问题:用double类型处理货币会有精度误差(比如0.1无法用二进制浮点数精确表示),可能导致后续计算出错。

修复步骤

1. 强制格式化字符串保留两位小数

把DecimalFormat的初始化代码改成指定格式,确保无论找零是整数还是小数,都会生成带小数点和两位小数的字符串:

DecimalFormat decimalFormat = new DecimalFormat("#.00");

这样整数找零会被格式化为"X.00",拆分后数组必然有两个元素,不会再出现越界。

2. 改用整数处理货币(推荐最佳实践)

把所有金额转换为以分为单位的整数,彻底避免浮点数精度问题。比如输入金额时先转成整数,找零直接用整数计算,不需要拆分字符串。

修改后的完整代码(优化版)

import java.util.Scanner;
import java.text.DecimalFormat;

public class CashRegister { // 类名首字母大写,符合Java规范
    public static void main(String[] args) {
        Scanner customerIn = new Scanner(System.in);
        
        // 输入金额时直接转换为分(整数)
        System.out.println("Please enter the sale amount");
        double saleAmt = customerIn.nextDouble();
        int saleCents = (int) Math.round(saleAmt * 100);
        
        System.out.println("Please enter amount tended by the customer");
        double cusTend = customerIn.nextDouble();
        int tendCents = (int) Math.round(cusTend * 100);
        
        // 计算找零(分)
        int changeCents = tendCents - saleCents;
        // 转换回元输出,保留两位小数
        System.out.printf("Total Change: %.2f%n", changeCents / 100.0);
        
        // 拆分美元和美分
        int dollars = changeCents / 100;
        int cents = changeCents % 100;
        
        // 计算各面额数量
        int quarters = cents / 25;
        cents %= 25;
        int dimes = cents / 10;
        cents %= 10;
        int nickels = cents / 5;
        int pennies = cents % 5;
        
        // 输出结果
        System.out.printf("\nDollars : %d%n", dollars);
        System.out.printf("Quarters : %d%n", quarters);
        System.out.printf("Dimes : %d%n", dimes);
        System.out.printf("Nickels : %d%n", nickels);
        System.out.printf("Pennies : %d%n", pennies);
        
        customerIn.close(); // 关闭Scanner,避免资源泄漏
    }
}

额外优化说明

  • 类名CashRegister首字母大写,符合Java命名规范
  • 用Math.round()处理浮点数转整数的精度问题(避免0.01元被截断为0分)
  • 简化了找零拆分逻辑,不需要再处理字符串拆分
  • 关闭了Scanner对象,避免资源泄漏
  • 用%n代替\n,实现跨平台换行

内容的提问来源于stack exchange,提问作者maddie pattie c

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:40:34