arithmeticexception需按场景差异化处理:整数除零应前置校验,math.exact溢出需降级,bigdecimal除法必设精度与舍入模式,动态表达式等少数情况才用try-catch捕获。

Java 中算术异常(ArithmeticException)不是一类模糊错误,而是明确指向非法算术操作的运行时异常。它不强制捕获,但一旦抛出且未处理,线程会中断。关键不是“要不要 catch”,而是“在哪拦、怎么防、为何这样选”。
区分不同触发场景,策略完全不同
同一个异常名,背后原因差异很大,处理方式不能一刀切:
-
整数除零或模零:如
10 / 0或5 % 0—— 这是逻辑错误,应提前校验,而非靠异常兜底 -
Math.exact 系列溢出:如
Math.addExact(Integer.MAX_VALUE, 1)—— 这是主动设计的溢出检测,用于替代静默截断,需预判或降级 -
BigDecimal 除法无限小数:如
new BigDecimal("1").divide(new BigDecimal("3"))—— 缺少精度与舍入模式,属于 API 使用不当 - Integer.MIN_VALUE / -1:整数取反溢出,极少见但合法触发,需在核心计算路径中特别注意
优先预防,而不是捕获
对除零、模零这类可静态判断的操作,把检查放在运算前更高效、更清晰:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 除法前加
if (divisor != 0),配合有意义的 fallback(如返回默认值、抛业务异常、记录告警) - 数据库字段或用户输入参与运算时,在 DTO 校验层或 Service 入口做非零断言,用
Objects.requireNonNull或自定义注解约束 - 避免写
try { x / y } catch (ArithmeticException e) { ... }来掩盖本可避免的逻辑漏洞
合理使用 try-catch 的三种典型场景
捕获只在以下情况真正必要:
- 动态表达式求值:比如解析用户输入的公式字符串,无法预知分母是否为零,此时 catch 并返回友好错误提示
-
Math.exact 降级路径:已知某些组合可能溢出,且有备用方案(如转
long或BigInteger),catch 后执行替代逻辑 -
全局兜底与可观测性:在 Spring 的
@ControllerAdvice中统一捕获,记录日志 + 返回标准错误码,避免堆栈暴露给前端
BigDecimal 除法必须指定精度和舍入模式
这个异常信息 Non-terminating decimal expansion 不代表计算失败,只说明你没告诉它“要保留几位、怎么舍入”:
- 正确写法:
a.divide(b, 2, RoundingMode.HALF_UP),明确 scale 和舍入规则 - 避免用
double构造 BigDecimal(如new BigDecimal(0.1)),会带入二进制浮点误差;改用字符串构造 - 财务类系统建议全程用整数单位(如“分”)+
long运算,绕开小数精度问题
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










