Java类型强转存在溢出、精度丢失和类型不匹配三大风险:数值越界导致结果不可预测,浮点转整型向零截断而非四舍五入,泛型/JSON中数字常为Double或Long,直接强转Integer会抛ClassCastException;应优先使用Math.toIntExact、校验范围或NumberUtils等安全方法。

Java 中把大范围类型转成小范围类型,不是“加个括号就完事”,而是直接截断、丢精度、甚至翻出负数——编译器不拦,运行时不报,错在逻辑里潜伏。
数值溢出:超出范围后结果不可预测
int 范围是 -2³¹ 到 2³¹−1(-2147483648 ~ 2147483647),一旦源值越界,强转后就是补码解释下的“乱码值”:
-
long → int:比如
long l = 3_000_000_000L;强转(int)l得到-1294967296,不是报错,也不是警告 -
int → byte:
int x = 200;→(byte)x结果是-56(只取低 8 位,符号位被误读) -
double → int:
double d = 3e9;→(int)d同样溢出,得负数
精度丢失:截断不四舍五入
浮点转整型时,Java 默认向零截断(truncation),不是四舍五入:
-
double d = 3.9;→(int)d得3;d = -3.9;→(int)d得-3 - 真要四舍五入,得先调
Math.round(d),再转——但注意Math.round(2.5)返回long,还要防 round 后再溢出
类型不匹配:不是精度问题,是根本不是那个类
泛型集合或 JSON 解析后常存的是 Double 或 Long,你写 (Integer)obj 会直接抛 ClassCastException:
立即学习“Java免费学习笔记(深入)”;
- Map
中的数字默认是 Double(Gson/Jackson 行为),不是Integer - 必须先用
obj instanceof Double判断,再取值、校验范围、转成 int - 推荐封装工具方法,如
NumberUtils.toInt(Number n),统一处理 null、类型分发、边界检查
安全替代方案:别裸写 (int)
JDK 提供了少数带溢出检查的工具,该用就得用:
-
Math.toIntExact(long):long → int,越界直接抛ArithmeticException -
Double.isFinite(d) && d >= Integer.MIN_VALUE && d <= Integer.MAX_VALUE:double → int 前的手动校验 -
Integer.valueOf(String)比裸强转更安全——它会解析并校验,非法字符串抛NumberFormatException


















