运行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
相关产品推荐
相关产品推荐

