防止精度丢失的关键是有策略地转换:优先用long/double/BigDecimal替代裸强转,字符串转数字禁用语法错误写法,小数转整数用Math.round或BigDecimal,大转小需校验溢出。

防止Java基本数据类型强制转换时精度丢失,核心不是“不转”,而是“有策略地转”——明确每一步转换的代价,用合适工具替代裸强转。
优先避开强制转换场景
很多所谓“必须强转”的需求,其实源于类型设计不合理:
- 整数运算统一用 long,避免 int 溢出(如计数器、时间戳差值)
- 浮点计算默认用 double,不用 float(float 有效位仅约7位,double 约15位)
- 金额、利率、百分比等业务值,直接用 BigDecimal,从源头绕过基本类型精度问题
- 字符串转数字,用 Integer.parseInt()、Double.parseDouble() 或 new BigDecimal(str),而不是写 (int)"123"(语法错误)
小数转整数:别用截断,用四舍五入
(int)3.9 得 3,(int)-3.9 得 -3 —— 这是丢弃小数位,不是数学取整:
- 正负数都需合理舍入:用 Math.round(double),它返回 long,再转 int 时注意类型匹配
- 要保留固定小数位(如价格保留两位),用 BigDecimal:
new BigDecimal(d).setScale(2, RoundingMode.HALF_UP)
大整数转小整数:加校验,不静默截断
long → int、int → byte 这类转换最易出错,JVM 不检查也不报错,只取低 N 位:
立即学习“Java免费学习笔记(深入)”;
- 用 JDK 内置安全方法:Math.toIntExact(long)、Math.toByteExact(int),超范围直接抛
ArithmeticException - 自己校验示例:
if (x >= Integer.MIN_VALUE && x - 需要“饱和处理”(溢出时取边界值),可用 Guava 的 Ints.saturatedCast()
警惕包装类拆箱和隐式提升陷阱
这些不是典型“强转”,但常引发类似精度/空指针问题:
-
Integer i = null; int x = i; → 抛
NullPointerException,必须判空或用Objects.requireNonNull() - byte b1 = 1, b2 = 2; b1 + b2 结果是 int,想存回 byte 必须显式
(byte)(b1 + b2) - 字面量 1 是 int,short s = 10; s = s + 1 编译失败,因 s+1 是 int 类型


















