java整数溢出静默截断,需提前识别风险、选用更大类型(如long替代int)、关键处用math.exact系列方法校验;浮点溢出则产生infinity或nan。

Java 中基本数据类型数值溢出不会抛异常,而是静默截断——这是必须接受的前提。处理的关键不是“阻止溢出”,而是提前识别风险、选择合适类型、必要时做主动校验。
理解溢出发生的底层机制
Java 所有整数类型都用二进制补码表示,固定位宽。当运算结果超出该类型的取值范围时,高位被直接丢弃,只保留低位有效字节。例如:
-
int 类型(32位)最大值是 2147483647,执行
2147483647 + 1得到的是 -2147483648; -
byte 类型(8位)赋值
byte b = (byte)300;,300 的二进制为00000001 00101100,截取低8位得00101100,即十进制 44。
优先用更大容量类型替代小类型
很多溢出其实源于过早选用小类型。除非有明确内存或IO约束,否则应按需升级:
- 计数器、ID、时间戳等场景,直接用
long替代int; - 循环索引、数组长度等 Java API 返回
int的地方,若涉及大集合(如 >2GB 数据),需检查是否可能越界; - 避免把
short或byte用于中间计算——它们在算术运算中会自动提升为int,反而增加隐式转换风险。
需要严格防溢出时手动校验
Java 8+ 提供了带溢出检查的静态方法,位于 Math 类中,推荐在关键逻辑中使用:
-
Math.addExact(a, b):相加,溢出则抛ArithmeticException; -
Math.multiplyExact(a, b)、Math.subtractExact(a, b)同理; -
Math.incrementExact(a)、Math.decrementExact(a)适合计数场景; - 对
long运算,对应方法名带Exact且参数为long,如Math.multiplyExact(long a, long b)。
注意浮点数的“溢出”不是同一概念
float 和 double 的溢出表现不同:超出范围时结果为 Infinity(正/负无穷)或 NaN(非数字),可通过 Double.isInfinite() 或 Double.isNaN() 检测。这和整数的静默回绕有本质区别,不能混为一谈。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











