Java强制类型转换需警惕溢出与截断:大转小会静默翻转,浮点转整型向零截断,引用类型转换须先判型,应优先使用Math.toIntExact等带溢出检查的API。

Java强制转换不是“加个括号就完事”,尤其从大范围类型(如double、long)转小范围类型(如int、short、byte)时,编译器不检查值是否越界,运行时也不会报错——它直接截断、丢精度或产生负数,结果往往出人意料。
基本转换要防溢出和截断
小范围类型有固定取值边界:byte是-128~127,short是-32768~32767,int是-2³¹~2³¹−1。超出就翻转,不是报错。
-
byte b = (byte) 200;→ 结果是-56(200对256取模再按补码解释) -
short s = (short) 32768;→ 结果是-32768 -
int i = (int) 3e9;→ 3000000000 > Integer.MAX_VALUE(2147483647),结果为-1294967296
浮点转整型:先想清楚要不要四舍五入
直接强转是向零截断:(int) 3.9得3,(int) -3.9得-3。若需四舍五入,必须显式调用Math.round(),但要注意round()返回long,仍可能溢出。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 安全截断:先用
Double.isFinite(d)排除NaN和无穷,再判断范围:d >= Integer.MIN_VALUE && d <= Integer.MAX_VALUE - 安全四舍五入:
long r = Math.round(d); int i = Math.toIntExact(r);(JDK 8+) - 别写
(int) Math.round(d)——万一round结果超int范围,会静默溢出
引用类型转换:类型匹配比精度更重要
泛型集合或JSON解析后常存的是Double或Long,直接(Integer) obj会抛ClassCastException,这不是精度问题,是类型不兼容。
立即学习“Java免费学习笔记(深入)”;
- 永远先用
obj instanceof Number确认是数字类型 - 再根据实际包装类分发处理:
obj instanceof Double→ 走浮点校验;obj instanceof Long→ 用Math.toIntExact((Long)obj) - 推荐封装工具方法:
NumberUtils.toInt(Number n),内部统一做null检查、类型判断、范围校验
用带溢出检查的工具替代裸强转
JDK 提供了少数真正“安全”的转换入口,它们会在越界时明确抛异常,而不是返回错误值。
-
Math.toIntExact(long):只接受long,溢出抛ArithmeticException -
Math.floorDiv(int, int)等运算类方法也自带溢出防护 - 金融、配置解析等关键场景,应优先使用这些API,而非
(int)或(short) - 连
Integer.valueOf(String)都比裸强转多一层解析校验,而(int) someDouble连异常都不抛

















