java数值溢出静默回绕是规范行为,需提前识别风险、选对类型(如用long替代int)、关键处用math.addexact等方法校验;浮点溢出结果为infinity或nan,须用isinfinite/isnan检测。

优先升级数据类型,避开溢出源头
很多溢出源于过早选用小类型。除非有明确约束(如协议字段、内存敏感场景),否则应按需升级:
- 计数器、ID、时间戳差值、分页总数等,直接用 long 替代 int;
- 数组长度、集合大小等虽由 API 返回 int,但若处理 >2GB 数据,需检查是否可能越界;
- 避免用 short 或 byte 做中间计算——它们会自动提升为 int,反而引入隐式转换风险。
关键逻辑必须做溢出校验
Java 8+ 提供了 Math.exact 系列方法,是轻量、高效、零依赖的标准解法:
-
Math.addExact(a, b)、Math.multiplyExact(a, b)、Math.subtractExact(a, b):溢出时抛
ArithmeticException,异常信息含 “integer overflow”,日志可直接定位; - 支持 int 和 long 重载,不支持 short/byte,使用前需先升为 int;
- 底层由 HotSpot 内联优化(如 x86 的
jo指令),性能几乎与原生运算一致,远优于手写边界判断或 long 中转再强转。
警惕那些容易被忽略的隐性溢出点
溢出常发生在看似安全的地方:
-
循环索引:如
for (int i = start; i ,当 <code>end == Integer.MAX_VALUE且step > 0,i可能回绕成负数,导致死循环; -
时间差值误存为 int:两个
System.currentTimeMillis()相减结果是 long,若强制转 int,精度直接丢失; -
用户输入或配置值参与计算前:只要接近边界(如配置项设为 2147483640),就该走
Math.addExact路径。
浮点溢出要单独对待
float/double 的“溢出”和整数完全不同:
- 超出范围时结果为 Infinity(正/负无穷)或 NaN(非数字);
- 可用
Double.isInfinite()或Double.isNaN()显式检测; - 不能用整数溢出思路去理解或处理,也不适用
Math.exact方法。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











