java表达式溢出静默回绕,发生在运算过程而非赋值时;类型提升不保安全,乘法链须从long起,二分查找需防left+right溢出。

Java 表达式计算中,中间结果溢出是隐蔽但高频的问题——它不报错、不告警,只静默回绕,比如 Integer.MAX_VALUE + 1 变成 Integer.MIN_VALUE。关键在于:**溢出发生在运算过程中,不是在赋值时;类型提升不等于安全,而只是运算规则的起点**。
乘法链必须从 long 开始
Java 按左结合顺序逐项推导类型,整个表达式类型由最左边操作数决定。哪怕结果变量声明为 long,若所有字面量都是 int,中间仍全程用 算,溢出后才转 <code>long,已无意义。
- 错误写法:
long millis = 60 * 24 * 3600 * 1000;→ 实际算出889032704(溢出值) - 正确写法:
long millis = 60L * 24 * 3600 * 1000;或long millis = (long) 60 * 24 * 3600 * 1000; - 同理,计算微秒:
long micros = 24L * 60 * 60 * 1000 * 1000;(而非24 * 60 * 60 * 1000 * 1000L,位置错就无效)
外部输入参与运算前先升为 long
用户传入的 int 值(如分页 offset、持续分钟数、时间差)看似安全,但一旦数值变大,offset * pageSize 或 minutes * 60 * 1000 就可能在中间阶段溢出。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 别写:
new Date(now + lastTime * 60 * 1000) - 改写为:
new Date(now + (long) lastTime * 60 * 1000)或更优:TimeUnit.MINUTES.toMillis(lastTime) - 根本解法:接口参数直接定义为
long lastTime,从源头切断int参与数学运算
用 Math.exact 系列主动捕获溢出
不是所有场景都适合无脑升 long。当业务逻辑要求“溢出即失败”(如金额扣减、库存校验),应显式检查而非依赖静默环绕。
-
Math.addExact(a, b)、Math.multiplyExact(a, b)、Math.toIntExact(longValue) - 溢出时抛
ArithmeticException,异常信息明确含 integer overflow,日志可直接定位 - 性能接近原生运算,JIT 有专门优化,不必担心开销
警惕隐性溢出点:索引、时间差、二分查找
溢出不只出现在大数相乘,这些地方常被忽略:
for (int i = start; i :若 <code>end == Integer.MAX_VALUE且step > 0,i加到最后会回绕成负数,导致死循环-
int diff = (int) (endTime - startTime):两个long时间戳相减可能超int范围,强制截断丢精度 → 改用long diff = endTime - startTime; - 二分查找中
int mid = (left + right) / 2:当left和right都接近MAX_VALUE时,left + right溢出 → 改为int mid = left + (right - left) / 2
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










