在Java中如何实现控制台版ATM系统_Java流程与逻辑实战解析
发布时间 - 2026-01-30 00:00:00 点击率:次ATM主菜单需用while(true)循环+nextLine()统一读输入并trim()防空格,避免nextInt()混用致换行符残留;账户余额用BigDecimal存于Account对象,交易记录用ArrayList保存;密码错误三次锁卡逻辑封装在Account内,失败计数与锁卡状态持久化;退出用标志位控制循环终止而非System.exit(0),确保资源释放与用户体验。
如何用Scanner和循环搭建ATM主菜单流程
Java控制台ATM系统的核心不是界面美观,而是状态流转不崩、输入不卡死。关键在于用Scanner读取用户选择后,必须消费掉换行符(尤其在nextInt()后紧接nextLine()时),否则后续输入会跳过。
推荐做法是统一用nextLine()读所有输入,再手动解析数字:
String input = scanner.nextLine().trim();
if ("1".equals(input)) {
showBalance();
} else if ("2".equals(input)) {
withdraw();
}
- 避免混用
nextInt()和nextLine(),这是最常导致“输入被跳过”的原因 - 每次读入后调用
trim(),防止空格干扰判断 - 主循环用
while (true)+break退出,比用标志变量更直觉
账户余额与交易记录怎么安全暂存
控制台ATM不需要数据库,但不能把余额写成静态变量——那样多个用户实例会互相污染。应为每个用户创建独立的Account对象,包含balance(double或更稳妥的BigDecimal)和transactions(ArrayList)。
注意:double做金额计算有精度风险,哪怕只是教学项目,也建议用BigDecimal初始化:
private BigDecimal balance = new BigDecimal("0.00");
-
withdraw()前必须校验amount.compareTo(balance) ,不能直接用比较BigDecimal - 交易记录建议存
LocalDateTime.now() + " 取款 " + amount,便于后续扩展 - 不要在
main()里直接操作字段,全部走getBalance()、deposit(BigDecimal)等方法封装
密码验证失败三次就锁卡怎么实现
这不是简单计数问题——锁卡状态必须跨操作保持,且不能靠全局静态变量(破坏封装)。正确做法是在Account类中加int failedAttempts和boolean isLocked,并在登录方法里联动控制:
if (account.isLocked()) {
System.out.println("卡片已锁定,请联系银行");
return false;
}
if (!inputPassword.equals(account.getPassword())) {
account.incrementFailCount(); // 内部自增并检查是否≥3
return false;
}
- 锁定逻辑要放在
Account内部,比如incrementFailCount()里自动设isLocked = failCount >= 3 - 成功登录后必须重置
failedAttempts = 0,否则下次登录直接锁 - 控制台无法真正“锁物理卡”,但状态必须持续
到程序重启前有效,所以不能只存在方法栈里
为什么System.exit(0)在ATM里要慎用
很多初学者在“退出系统”选项里直接写System.exit(0),这会导致JVM立即终止——未保存的交易日志丢失、资源没释放、甚至可能让正在执行的取款操作中断在半途。
更稳妥的做法是让主循环自然退出:
boolean running = true;
while (running) {
showMainMenu();
String choice = scanner.nextLine().trim();
switch (choice) {
case "0": running = false; break; // 正常退出
case "1": ...
}
}
System.out.println("感谢使用,再见!");
- 仅在极端异常(如文件写入失败且无法恢复)时才考虑
System.exit(1) - 如果用了
try-with-resources打开日志文件,自然退出能保证close()被执行 - 用户看到“再见”提示,比进程突然消失更符合控制台程序的交互预期
真正的难点不在功能堆砌,而在于每个操作的边界是否清晰:一次取款是不是原子的?密码错误计数会不会被并发访问搞乱?这些在单线程控制台里看似无关,但逻辑一旦写歪,后面加任何功能都会踩坑。
# word
# java
# 栈
# ai
# switch
# 并发访问
# 为什么
# jvm
# String
# Boolean
# while
# 封装
# try
# break
# int
# double
# 循环
# 堆
# 线程
# 并发
# 对象
# 数据库
# 跳过
# 这是
# 是在
# 放在
# 多个
# 不需要
# 会不会
# 并在
# 半途
# 用了
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
iOS中将个别页面强制横屏其他页面竖屏
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
Laravel如何使用Vite进行前端资源打包?(配置示例)
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
HTML 中动态设置元素 name 属性的正确语法详解
Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
Laravel如何使用Sanctum进行API认证?(SPA实战)
Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】
如何在云主机上快速搭建多站点网站?
如何在香港服务器上快速搭建免备案网站?
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
Swift中switch语句区间和元组模式匹配
新三国志曹操传主线渭水交兵攻略
详解Huffman编码算法之Java实现
HTML 中如何正确使用模板变量为元素的 name 属性赋值
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
如何快速生成专业多端适配建站电话?
edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】
如何快速重置建站主机并恢复默认配置?
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
Swift中循环语句中的转移语句 break 和 continue
小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像
Laravel如何处理和验证JSON类型的数据库字段
php做exe能调用系统命令吗_执行cmd指令实现方式【详解】
香港服务器网站卡顿?如何解决网络延迟与负载问题?
如何选择可靠的免备案建站服务器?
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
javascript事件捕获机制【深入分析IE和DOM中的事件模型】
Laravel怎么调用外部API_Laravel Http Client客户端使用
如何在宝塔面板创建新站点?
Laravel Session怎么存储_Laravel Session驱动配置详解
Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】
WordPress 子目录安装中正确处理脚本路径的完整指南
Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】
bing浏览器学术搜索入口_bing学术文献检索地址
如何在腾讯云服务器上快速搭建个人网站?
微信小程序 wx.uploadFile无法上传解决办法
Linux系统命令中screen命令详解
如何快速使用云服务器搭建个人网站?
敲碗10年!Mac系列传将迎来「触控与联网」双革新
Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用
Firefox Developer Edition开发者版本入口


