Java ATM机自动取款机毕业设计:从零实现一个高仿真的银行终端系统
·
Java ATM机自动取款机毕业设计:从零实现一个高仿真的银行终端系统
大三那年,我也被“ATM 模拟系统”支配过:界面一跑就崩、余额能取成负数、多线程下同一账户被刷爆,答辩现场尴尬到脚趾抠地。
本笔记把踩过的坑一次性打包,带你用纯 Java SE(零框架)写出一个能跑、能看、还能防“熊孩子”的银行终端,毕业设计直接提档。

一、学生项目常见“车祸”现场
-
逻辑漏洞
- 取款只判断
if (money <= balance),忘了负数,结果输入 -1000,余额反涨。 - 存款写
balance += money后,直接打印成功,中途宕机钱就凭空消失。
- 取款只判断
-
安全“纸糊”
- 卡号、密码硬编码在
main方法,一改需求全文件搜索。 - 多线程场景下,两个窗口同时扣款,出现“并发超支”,老师一按 F5 现场翻车。
- 卡号、密码硬编码在
-
演示“社死”
- 控制台
Scanner读字符串,空格一多就抛InputMismatchException,现场重启。 - 没有交易记录,老师问“怎么追溯?”——只能尴尬微笑。
- 控制台
二、技术选型:为什么只用 Java SE
| 方案 | 优点 | 缺点(对学生) |
|---|---|---|
| Java SE + 文件 | 语法点全覆盖,轻量,单 jar 跑 | 自己写序列化,IO 异常多 |
| Spring Boot + MySQL | 企业级,简历好看 | 配置能把新手劝退,答辩时间全调 XML |
| JavaFX + SQLite | 界面好看 | 要学 UI 线程,答辩现场分辨率一变就错位 |
结论:毕业设计核心在“业务逻辑 + 编码规范”,Java SE 足够,把 OO、异常、并发、集合、IO 五个考点串起来就能拿高分。
三、核心实现:三张类图跑通全场
1. 账户类(Account)——只做数据,不干业务
public final class Account {
private final String cardId; // 卡号,final 防篡改
private final String pin; // 6 位密码,明文仅 Demo
private BigDecimal balance = BigDecimal.ZERO;
public boolean validatePin(String input) { return pin.equals(input); }
// 余额变动统一入口,synchronized 保证线程安全
public synchronized boolean changeBalance(BigDecimal delta) {
BigDecimal newVal = balance.add(delta);
if (newVal.compareTo(BigDecimal.ZERO) < 0) return false;
balance = newVal;
return true;
}
// 省略 getter / toString
}
要点
BigDecimal解决 double 精度坑。synchronized直接加在对象级,毕业设计场景够用,后续可升级ReentrantLock。
2. ATM 控制器(AtmController)——流程门面
public class AtmController {
private final Map<String, Account> accountDB = new HashMap<>();
private final Deque<Transaction> logQueue = new ArrayDeque<>();
public Session login(String cardId, String pin) {
Account acc = accountDB.get(cardId);
if (acc == null || !acc.validatePin(pin))
throw new SecurityException("卡号或密码错误");
return new Session(acc); // 每次登录新建会话
}
public void withdraw(Session s, BigDecimal amount) {
validateAmount(amount);
if (!s.getAccount().changeBalance(amount.negate()))
throw new IllegalArgumentException("余额不足");
log(new Transaction(s.getCardId(), "WITHDRAW", amount));
}
private static void validateAmount(BigDecimal amount) {
if (amount.compareTo(BigDecimal.ZERO) <= 0)
throw new IllegalArgumentException("金额必须为正");
}
// 其余 deposit、queryBalance、getLogs 同理
}
要点
- 所有业务走控制器,不暴露 Account 引用,防止外部直接改余额。
- 交易日志先写内存队列,演示时可 flush 到文件,体现“持久化”思想。
3. 交易记录(Transaction)——值对象,不可变
public record Transaction(String cardIdoka, String type,
BigDecimal amount, LocalDateTime ts) {
public Transaction(String cardId, String type, BigDecimal amount) {
this(cardId, type, amount, LocalDateTime.now());
}
}
用 record 一行写完,天然线程安全、toString/json 都省心。
四、Clean Code 示例:一个完整取款流程
// 客户端代码,main 方法片段
1. 读卡号、密码
2. 调用 AtmController.login → 拿到 Session
3. 循环菜单:
3.1 选 1 查询 → controller.queryBalance(session)
3.2 选 2 取款 →
- 控制台读金额 → new BigDecimal(input)
- controller.withdraw(session, amount)
- 打印“出钞口请取走现金 ¥xxx”
3.3 选 3 退卡 → break,session 失效
每个方法 < 20 行,拒绝“一大坨 main”。
五、安全性 & 健壮性 checklist
-
输入校验
- 金额必须
> 0,正则\d{1,8}(\.\d{0,2})?防字母。 - 密码连续输错 3 次锁定卡号,用
AtomicInteger计数。
- 金额必须
-
并发安全
Account.changeBalance已同步;- 控制器里再加一层
synchronized (account)双保险,演示时老师拿 JMeter 多线程刷也稳。
-
异常链
- 业务抛
IllegalArgumentException,最外层统一 catch 打印“友好提示”,堆栈留 log 文件,老师问“怎么排错?”直接翻日志。
- 业务抛
-
边界用例
- 余额 0 元取 1 分 → 提示“余额不足”。
- 输入 0.333 → 精度截断到分,BigDecimal.setScale(2, HALF_UP)。
六、生产环境避坑指南(毕业级也适用)
-
拒绝硬编码
- 卡号、密码放
config.properties,用Properties类加载。 - 每日限额、单笔限额也抽出来,老师问“怎么改限额?”改配置即可。
- 卡号、密码放
-
日志不能
System.out.println- 引入
java.util.logging或logback-core(纯 JavaSE 也能用),一行LOG.log(Level.INFO, "withdraw {0} by {1}", new Object[]{amount, cardId});逼格瞬间满。
- 引入
-
线程中断别吞
- 文件刷盘时
Thread.sleep(500)必须包try{...} catch (InterruptedException e){ Thread.currentThread().interrupt(); },老师问“中断信号怎么处理?”答得上口。
- 文件刷盘时
-
资源关闭
- 读写文件用
try-with-resources,自动关流,省得答辩时被问“内存泄漏怎么办?”
- 读写文件用
七、可扩展方向(把答辩老师问倒)
-
转账功能
- 控制器新增
transfer(Session from, String toCardId, BigDecimal amount),事务性使用synchronized (fromAccount) { synchronized (toAccount) { ... } },注意顺序防死锁。
- 控制器新增
-
PIN 加密
- 密码存 BCrypt 哈希,登录时
BCrypt.checkpw(input, hashed);引入jbcrypt单 jar 即可。
- 密码存 BCrypt 哈希,登录时
-
持久化存储
- 账户快照用
ObjectOutputStream写accounts.dat,启动时readObject恢复; - 交易流水追加写 CSV,演示完直接 Excel 打开,老师直呼专业。
- 账户快照用
-
图形界面
- 学完 JavaSE 后可平滑迁移 JavaFX,控制器层零改动,只换 UI 交互,体现“前后端分离”思想。
八、打包 & 演示小技巧
- 用
maven-assembly-plugin一键打可执行 jar:java -jar atm.jar直接跑,教室电脑没 IDEA 也能秀。 - 提前录屏 2 分钟,现场万一投影挂掉,放视频保底。
- 把“多线程扣款”脚本也带上,老师想看并发效果时当场跑,稳。
九、小结:从“能跑”到“能吹”
把 Account 做成不可变数据 + 同步写余额,Controller 当门面统一校验,Transaction 用记录对象把日志串起来,一套组合拳下来,代码量不到 800 行,却覆盖了 OO、并发、异常、IO、集合五大考点。答辩时老师问“如果余额字段被反射改掉怎么办?”你还能笑着接茬“可以加 SecurityManager 或者把 balance 放 AtomicReference 里 CAS 保证。”——毕业设计直接优秀。
下一步,不妨给系统加上转账、加密和数据库,把它当成真正的“迷你银行”练手项目。祝你一次通过,早日把键盘收入囊中!
更多推荐





所有评论(0)