DecimalFormat格式化结果为String,不可直接用于数学运算;需参与计算时应优先使用BigDecimal配合setScale和HALF_UP模式确保精度与四舍五入可控。

DecimalFormat 格式化后仍是字符串,别直接当数字用
很多人用 DecimalFormat 把 double 格式化成两位小数,结果发现返回的是 String,后续想做加减乘除就报错或出错。这不是 bug,是设计如此——它只负责「显示格式」,不改变原始数值精度。
- 用
new DecimalFormat("0.00")格式化1.2得到"1.20",但"1.20" + 1是字符串拼接,不是数学运算 - 如果真要参与计算,得先用
Double.parseDouble()转回数字,但注意:这会丢失你“保留两位”的意图(比如1.205四舍五入成"1.21"后再转回double,其实还是浮点误差) -
DecimalFormat默认使用当前 Locale 的小数点符号,中文环境没问题,但部署到英文服务器可能输出"1,234.56",记得显式设setDecimalSeparator('.')
String.format("%,.2f") 会自动四舍五入,但要注意负数和大数
String.format 看似简单,实际行为比直觉更“重”:它底层调用 Formatter,对浮点数执行 IEEE 754 规则下的四舍五入(银行家舍入?不,是传统四舍五入),且受 Locale 影响。
-
String.format("%.2f", 1.235)→"1.24";String.format("%.2f", -1.235)→"-1.24"(负数也正常四舍) - 加逗号分隔符时:
String.format("%, .2f", 1234567.891)→"1,234,567.89",注意空格位置影响对齐 - 传入
null或非数字类型会抛NullPointerException或IllegalFormatConversionException,线上别裸用
真正需要“保留两位小数并参与计算”?用 BigDecimal
如果你的场景是金额、计费、金融类逻辑,要求「精确保留两位、四舍五入可预期、能安全参与后续运算」,DecimalFormat 和 String.format 都不该是第一选择。
- 别用
new BigDecimal(double)构造,比如new BigDecimal(1.1)实际存的是1.100000000000000088817841970012523233890533447265625 - 正确做法是传字符串:
new BigDecimal("1.1").setScale(2, RoundingMode.HALF_UP) -
setScale(2, RoundingMode.HALF_UP)才是你想要的“传统四舍五入”,不是默认的HALF_EVEN - 运算后记得再
setScale,因为add/multiply默认保留更多位数
Android 里 TextView 显示两位小数,别在 Java 层格式化
Android 开发中常见需求:把一个价格数字塞进 TextView,显示为带两位小数的样式。这时候在 Activity/Fragment 里用 DecimalFormat 或 String.format 拼字符串,其实是多此一举。
立即学习“Java免费学习笔记(深入)”;
- 推荐在 XML 里用
android:text="@{@string/price_format(model.price)}"配合@string/price_format定义为%.2f 元,由 DataBinding 处理 - 或者用
TextView.setText(String.format("%.2f", price) + " 元")—— 简单直接,别封装成工具方法来回调 - 避免在
Adapter的onBindViewHolder里反复 newDecimalFormat,它不是线程安全的,也不轻量,复用static final实例更稳妥
DecimalFormat 还是 String.format,都只改字符串表现,不碰数值本质。真要控精度,绕不开 BigDecimal 和明确的 RoundingMode。










