java基本类型转换溢出会静默截断,应优先用math.exact系列方法抛arithmeticexception,其次手动范围校验,避免double中间态,并在输入层用注解统一拦截非法值。

Java 中基本数据类型转换时的数值溢出,不会自动报错,而是静默截断或符号翻转——比如 (byte)128 得到 -128,(int)Double.MAX_VALUE 变成 Integer.MIN_VALUE。这种“看起来运行正常、结果完全错误”的行为,才是最危险的。关键不是等它出错后再修复,而是在转换前就堵住入口。
用 Math.exact 系列方法替代裸强转
JDK 8+ 提供了带溢出检查的工具方法,失败时明确抛 ArithmeticException,让问题暴露在开发或测试阶段:
-
Math.toIntExact(long value):比(int)longValue多一层校验,超 int 范围直接中断 -
Math.toShortExact(int value)、Math.toByteExact(int value)同理适用 - 浮点转整需先取整再校验:
Math.toIntExact((long)Math.round(d)),避免(int)d的截断和精度丢失
转换前手动范围校验是兜底手段
当不能抛异常(如需返回默认值或降级处理),必须自己做显式判断:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- double → int:
Double.isFinite(d) && d >= Integer.MIN_VALUE && d - long → int:
value >= Integer.MIN_VALUE && value - int → byte:
i >= Byte.MIN_VALUE && i
注意:校验必须在转换动作之前完成,且不能依赖转换后的值反推是否溢出——因为结果已失真。
避免 double 中间态放大误差
浮点数本身存在精度限制(如 float 仅能精确表示 ±2²⁴ 内的整数),再经强制转换会雪上加霜:
- 不要写
(int)someDouble,它既不四舍五入也不校验,还可能因精度丢失导致越界 - 需要取整时,优先用
Math.round()或BigDecimal控制舍入模式 - 金融、ID、计数等关键场景,应从源头避免使用 double 表达整数
包装类 + 注解实现输入层统一拦截
外部数据(如 HTTP 参数、配置文件)进入系统时,就该把非法值拦在外面:
- 参数类型改用
Integer、Long等包装类,才能被@Min/@Max注解识别 - 定义通用注解如
@InIntRange,内部复用Integer.MIN_VALUE/MAX_VALUE校验逻辑 - Spring Boot 中开启
@Validated,让校验在绑定阶段触发,不进业务代码
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










