java整数溢出会静默回绕而非报错,需从四方面预防:①用math.addexact等方法主动捕获溢出;②升级为long并确保运算不先按int执行;③循环累加等优先改用long;④高频场景手动预检边界。

Java 中整数溢出不会报错,而是静默回绕——比如 Integer.MAX_VALUE + 1 得到的是 -2147483648。这不是 bug,是补码机制下的确定行为,但极易引发逻辑错误。关键不是“能不能发现”,而是“怎么提前防住”。下面从四个实用角度展开。
用 Math.exact 系列方法主动捕获溢出
Java 8 起提供了带溢出检查的数学工具方法,加减乘除都覆盖,失败时抛 ArithmeticException,比事后调试高效得多。
-
Math.addExact(a, b):两 int 相加,超范围立即抛异常 -
Math.multiplyExact(a, b):乘法同样适用,避免100000 * 100000溢出成负数 - 适用于业务逻辑关键路径,如计费、库存扣减、ID 生成等不允许静默错误的场景
升级为 long 类型扩大安全边界
int 最大值约 21 亿,long 最大值超 900 亿亿,对大多数中间计算已足够。但要注意:类型升级不等于自动防溢出,必须确保运算过程本身不先按 int 执行。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 错误写法:
long x = 2147483647 + 1;→ 先算 int 加法再赋值,结果已是 -2147483648 - 正确写法:
long x = 2147483647L + 1;或long x = (long)2147483647 + 1; - 循环累加、指数增长(如
x = 3 * x)优先改用long,可多撑十几轮迭代
手动预检边界,适合高性能场景
在高频调用或资源受限环境(如嵌入式、高频交易),避免异常开销,可提前判断是否溢出。
- 加法检查:
if (a > 0 && b > Integer.MAX_VALUE - a)→ 必溢 - 减法检查:
if (a → 必溢 - 乘法较复杂,需分符号组合判断;推荐直接用
Math.multiplyExact,除非压测证明它是瓶颈
超大数用 BigInteger,不妥协精度
当数值无法预估上限(如阶乘、密码学运算、天文计算),BigInteger 是唯一选择。它基于数组实现,精度只受内存限制。
- 不能用
+*运算符,必须调用.add()、.multiply()等方法 - 转换示例:
BigInteger.valueOf(100).multiply(BigInteger.TEN) - 代价是对象创建开销和 GC 压力,避免在简单循环中滥用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










