math.addexact 抛出 arithmeticexception 是设计行为,用于主动捕获整数溢出;应通过 try-catch 降级处理或加法前手动检查溢出,优先选用合适数值类型并覆盖边界用例测试。

遇到 Math.addExact 抛出 ArithmeticException,说明加法结果超出了 int 或 long 的取值范围。这不是 bug,而是设计行为——它主动帮你捕获溢出,避免静默错误。关键在于:**别让它抛异常,而要提前判断或合理兜底**。
用 try-catch 主动捕获并降级处理
这是最直接的方式,适合你明确知道某些输入可能溢出、且有备用逻辑的场景(比如计数器达到上限后转为 BigInteger 或返回默认值):
- 捕获
ArithmeticException,而不是泛 catchException - 在 catch 块中做有意义的处理,比如记录日志、返回 null、切换到大数运算,或抛出自定义业务异常
- 避免空 catch 或只打印堆栈却不处理——这会让问题被掩盖
示例:
try {
int result = Math.addExact(a, b);
return result;
} catch (ArithmeticException e) {
// 溢出时改用 long 运算(如果 a,b 是 int)
return (long) a + (long) b; // 或转 BigInteger
}
加法前手动检查是否溢出
如果你追求零异常开销(如高频计算场景),可先用 Math.addExact 的底层逻辑做预判。Java 本身提供了 Math.addExact 的等价检查方式:
- 对
int:检查(a > 0 && b > 0 && a > Integer.MAX_VALUE - b)或(a - 对
long:类似,用Long.MAX_VALUE/Long.MIN_VALUE - 更稳妥的做法是直接调用
Math.addExact并捕获异常——JVM 对它的优化很好,实际性能差异通常可忽略
根据业务需求选择更合适的类型或 API
溢出频繁出现?说明当前数值范围可能不匹配业务规模:
- 若结果可能很大,优先考虑用
long替代int,或直接用BigInteger(无溢出,但有性能和内存代价) - 若只是累加计数且允许“饱和”(即到最大值后不再增长),可用
Math.addExact+ catch 后返回Integer.MAX_VALUE等饱和值 - JDK 8+ 还提供
Math.incrementExact、Math.decrementExact、Math.multiplyExact等,统一风格处理各类精确运算
单元测试必须覆盖溢出边界用例
用 Math.addExact 的地方,光测正常值不够。务必验证边界情况:
-
Integer.MAX_VALUE + 1、Integer.MIN_VALUE - 1 - 正负极大值相加(如
MAX_VALUE + MIN_VALUE不溢出,但MAX_VALUE + 1会) - 用 JUnit 的
@Test(expected = ArithmeticException.class)或 AssertJ 的catchThrowable()显式断言异常发生
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











