一、Java如何存储金额
Java 存储金额有两种方式,一般选第二种
- 使用
long, 精度表示 分 (涉及汇率、税率可能出问题) - 使用
BigDecimal,同时 MySQL 表字段使用decimal(p, q)
-
p:总精度,最多 p 位有效十进制数字。 -
q:小数位数,保留 q 位小数。 -
整数部分最多为
p - q位。
二、BigDecimal 的经典问题
1. 比较数值不能直接依赖 equals()
equals() 不仅比较数值,还比较小数位数(scale)。
java
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("1.00");
System.out.println(a.equals(b)); // false
System.out.println(a.compareTo(b)); // 0
使用 compareTo() 比较金额大小
2. 不推荐通过 float / double 构造 BigDecimal
java
BigDecimal a = new BigDecimal(0.1);
System.out.println(a);
// 0.1000000000000000055511151231257827021181583404541015625
正确写法:
java
// 推荐:使用字符串
BigDecimal a = new BigDecimal("0.1");
// 也可以:使用 valueOf()
BigDecimal b = BigDecimal.valueOf(0.1);
3. BigDecimal 是不可变对象,计算时需要接收返回值
java
BigDecimal price = new BigDecimal("100");
price.add(new BigDecimal("20"));
System.out.println(price); // 100
4. 除法可能抛异常 ArithmeticException
java
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("3");
a.divide(b); // 抛出 ArithmeticException
应该指定精度和舍入模式
java
BigDecimal result = a.divide(
b,
2,
RoundingMode.HALF_UP
);
System.out.println(result); // 3.33
-
2:保留两位小数。 -
HALF_UP:常见的四舍五入模式。
封面
