Java 存储金额

一、Java如何存储金额

Java 存储金额有两种方式,一般选第二种

  1. 使用long, 精度表示 分 (涉及汇率、税率可能出问题)
  2. 使用 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:常见的四舍五入模式。

封面

相关推荐
大哥43091 小时前
模型名停用与分层降级:一次 LLM 链路的失败面设计
后端
橙子家1 小时前
对象状态与操作合法性异常【C# Exception 详解系列(二)】
后端
SL_staff2 小时前
周报越厚问题越拖?用结构化执行机制让周报回归决策价值
java·spring cloud·开源
架构技术专栏2 小时前
为什么 AI 公司都想做Personal Agent ?
后端
梅梅绵绵冰2 小时前
JVM虚拟机
java·开发语言·jvm
golang学习记2 小时前
Python vs Go:2026年到底该怎么选
java·vscode·python·golang·pycharm·goland
用户761016088472 小时前
黑马RabbitMQ 从入门到可靠性:收发、持久化、死信延迟一篇打通
后端
Bazingga2 小时前
Transformer与自注意力机制:一台"全员检索"机器的说明书
人工智能·后端
Shaoshing2 小时前
消息顺序
java·开发语言