java类型转换危险在于默认信任其语义正确性:浮点转整数需明确取整意图,避免向零截断;高精度整型降级前必须范围校验,否则静默溢出。

Java类型转换本身不危险,危险的是默认信任它能“正确处理”。精度丢失和溢出不是偶发错误,而是类型系统按设计执行的结果——你没写错语法,只是没告诉程序“你要什么语义”。
浮点数转整数:别用(int)截断,要明确取整意图
直接写 (int) 3.9 得到 3,(int) -3.9 得到 -3,这是向零截断,不是四舍五入。业务中多数场景需要的是“离最近整数更近”的结果。
- 需要四舍五入:用
Math.round(d)(返回long)或Math.round(f)(返回int),注意类型差异 - 需要防溢出转
int:用Math.toIntExact(Math.round(d)),超范围直接抛ArithmeticException - 仅需丢弃小数:确认业务真接受“砍掉”,而不是“向下取整”或“保留符号的截断”
高精度整型转低精度:先检查,再转换
long id = rs.getLong("order_id"); int orderId = (int) id; 看似无害,但第 2147483648 个订单就会变成负数。强制转换不会报错,只会静默绕回。
- 整型降级前做范围校验:
if (value >= Integer.MIN_VALUE && value - 优先用 JDK 提供的安全方法:
Math.toIntExact(longValue)、Math.toShortExact(intValue) - 若允许饱和(溢出取边界值),可用 Guava 的
Ints.saturatedCast(longValue)
浮点数精度陷阱:float → double 不是“升级”,而是“复制近似值”
float f = 12.8F; 存储的其实是 12.800000190734863;double d = f; 只是把这个近似值扩展成 double 格式,并未恢复真实十进制值。所以 d == 12.8 为 false。
- 需要精确表示十进制数(如金额、配置值):从字符串构造,例如
Double.valueOf("12.8")或new BigDecimal("12.8") - 避免用
double做等值判断:改用Math.abs(a - b) ,或统一转 <code>BigDecimal比较 - 金融计算等关键场景:全程使用
BigDecimal,单位用“分”代替“元”,规避浮点表示根本缺陷
运算阶段就防溢出:别等赋值才补救
int money = 1_000_000_000; int years = 30; long total = money * years; ——乘法已在 int 范围内溢出,再赋给 long 也晚了。
- 提前升维:写成
(long) money * years或money * (long) years - 声明即高精度:对累计值、ID、时间戳毫秒等,直接声明为
long,不依赖后期转换 - 大数超出
long范围时:用BigInteger,它以字符串方式存储,无固定上限
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











