Java使用Scanner获取用户double类型输入的代码问题排查
代码问题定位与修正
你的代码存在5个直接导致功能不符合预期的错误,按影响优先级排序:
- 局部变量未初始化就使用:main方法中定义的
double availAmount;是局部变量,没有赋值就传入upgradeAccessories()方法,既不符合Java语法要求(编译阶段就可能报错),实际运行时传入的也是无意义的脏值,和后续用户输入的金额没有任何关联。 - 输入逻辑顺序完全颠倒:你把接收用户输入的
sc.nextDouble()放在了金额计算、升级前金额打印逻辑的后面。正确逻辑应该是先打印输入提示、接收用户输入的初始金额,再拿着这个金额做升级计算;现在的执行流程是先拿脏值算完结果、打印提示,才停下来等用户输入,且输入拿到的值存在upgradeAccessories变量后没有参与任何后续计算,属于完全无效的代码。 - 重复调用方法引发状态错误:你连续两次调用
owner.upgradeAccessories()方法,第一次调用命中判断分支后,就会修改车辆配置的安装状态、扣减金额,第二次调用会在第一次扣减后的剩余金额基础上再次做判断,既拿不到正确的升级前金额,还会导致配置状态、剩余金额计算完全错误。实际上升级前金额就是用户输入的初始值,只需要调用一次方法,传入初始金额,返回值就是升级后的剩余金额。 - 浮点数直接用
==判断存在精度隐患:upgradeAccessories方法中直接用==判断double类型的金额是否等于固定阈值,double类型存在浮点精度误差,即使用户准确输入25000,实际存储值也可能是24999.999999999996,导致判断分支无法命中,配置安装、金额扣减逻辑完全不执行。 - 输入提示未正常刷新:你用
System.out.print()打印输入提示时没有加换行符,控制台缓冲区可能不会立刻输出提示文本,用户看不到输入提示就会以为程序卡住,不知道需要输入金额。
修正后核心代码参考
public static void main(String[] args) { DecimalFormat df = new DecimalFormat("#####"); Scanner sc = new Scanner(System.in); Car owner = new Car(); owner.owner("Marcus Laurence", 2014); // 先输出提示,再接收用户输入的初始可用金额 System.out.print("Available Amount Before Upgrade:"); double availAmount = sc.nextDouble(); // 保存升级前金额,避免后续计算覆盖原始值 double availAmountBefore = availAmount; // 仅调用一次升级计算方法,拿到剩余金额 double remainAmount = owner.upgradeAccessories(availAmount); System.out.println("Owner:" + owner.name); System.out.println("Model:" + owner.model); System.out.println(df.format(availAmountBefore)); System.out.println("Installed AC:" + owner.hasAC); System.out.println("Installed Leather Seats:" + owner.hasLeatherSeats); System.out.println("Installed Back Wipers:"+ owner.hasBackWipers); System.out.println("Installed Fog Lights:" + owner.hasFogLights); System.out.println("Amount Remaining After Upgrade:" + df.format(remainAmount)); sc.close(); } // 方法内的浮点数判断改成差值范围判断,规避精度问题 public double upgradeAccessories(double availAmount) { if(Math.abs(availAmount - 25000) < 0.001) { availAmount -= 21500; hasAC=true; } else if(Math.abs(availAmount - 40000) < 0.001) { availAmount -= 21500; availAmount -= 14400; hasAC=true; hasLeatherSeats=true; } else if(Math.abs(availAmount - 50500) < 0.001) { availAmount -=21500; availAmount -=14400; availAmount -=6250; availAmount -=3300; hasAC=true; hasLeatherSeats=true; hasBackWipers=true; hasFogLights=true; } return availAmount; }
内容的提问来源于stack exchange,提问作者John Cennon
相关产品推荐
相关产品推荐

