一、核心定位
- 用途:解决
double/float精度丢失问题,专门处理高精度小数场景(如金额、税率、礼品卡余额等)。 - 核心优势:存储精确、计算安全、支持自定义舍入规则和小数位数。
二、创建方式(避坑关键)
| 创建方式 | 代码示例 | 适用场景 | 注意事项 |
|---|---|---|---|
| 字符串构造(推荐) | new BigDecimal("100.50") | 金额、复杂小数 | 无精度丢失,最安全 |
静态方法 valueOf(推荐) | BigDecimal.valueOf(100.50) | 基本类型小数、整数 | 内部转字符串,无精度丢失 |
| double 构造(绝对禁止) | new BigDecimal(100.50) | 无(绝对不用) | 存在隐藏精度丢失,金额场景禁用 |
三、核心操作(不可变类,需接收返回值)
1. 加减乘除(金额计算核心)
| 操作 | 方法 | 代码示例(礼品卡场景) |
|---|---|---|
| 加法 | add(BigDecimal val) | BigDecimal newBalance = balance.add( rechargeAmount); // 余额 + 充值金额 |
| 减法 | subtract(BigDecimal val) | BigDecimal newBalance = balance.subtract(consumeAmount); // 余额 - 消费金额 |
| 乘法 | multiply(BigDecimal val) | BigDecimal discountAmount = amount.multiply(new BigDecimal("0.9")); // 9 折 |
| 除法 | divide(除数, 小数位, 舍入模式) | BigDecimal split = total.divide(new BigDecimal("3"), 2, RoundingMode.HALF_UP); // 平分,保留 2 位小数 |
2. 比较大小(禁用 ==)
| 比较场景 | 代码示例 | 结果说明 |
|---|---|---|
| 等于 | a.compareTo(b) == 0 | true 表示两值相等 |
| 大于 | a.compareTo(b) > 0 | true 表示 a > b |
| 大于等于 | a.compareTo(b) >= 0 | 余额≥消费金额时可用 |
| 小于 | a.compareTo(b) < 0 | true 表示 a < b |
3. 小数位数与格式化
| 需求 | 代码示例 | 效果 |
|---|---|---|
| 保留 2 位小数(四舍五入) | a.setScale(2, RoundingMode.HALF_UP) | 100.1 → 100.10 |
| 千分位 + 2 位小数 | new DecimalFormat("#,##0.00").format(a) | 2000.5 → 2,000.50 |
| Hutool 简化格式化 | NumberUtil.round(a, 2) | 直接保留 2 位小数,无需手动写模式 |
四、常用舍入模式(金额场景优先用前 2 个)
| 模式 | 说明(小白白话版) | 示例(保留 1 位小数) |
|---|---|---|
RoundingMode.HALF_UP | 四舍五入(日常常用) | 100.55 → 100.6 |
RoundingMode.DOWN | 直接舍去小数(不进 1) | 100.59 → 100.5 |
RoundingMode.UP | 小数位非 0 则进 1(不舍弃) | 100.51 → 100.6 |
RoundingMode.HALF_DOWN | 五舍六入(少用) | 100.55 → 100.5 |
五、小白必避坑
- 绝对不用
new BigDecimal(double):避免精度丢失; - 操作后必须接收返回值:BigDecimal 不可变,原对象不会被修改;
- 除法必须指定小数位和舍入模式:否则除不尽时抛异常;
- 金额统一保留 2 位小数:避免后续计算精度累积;
- 禁用
==比较:必须用compareTo方法。
238

被折叠的 条评论
为什么被折叠?



