安全转long为int应优先用Math.toIntExact(),它校验范围并越界抛ArithmeticException;手动校验需显式判断value≥Integer.MIN_VALUE且≤Integer.MAX_VALUE。

Java 中把 long 安全转为 int,核心不是“怎么转”,而是“怎么确认能转”。因为直接写 (int) value 会静默截断——2147483648L 变成 -2147483648,订单号、时间戳、计数器一变负就出大问题。
用 Math.toIntExact() 最省心
这是 JDK 8+ 提供的官方安全方法,专为这种场景设计:
- 它只接受
long参数,内部做完整范围校验 - 值在
Integer.MIN_VALUE到Integer.MAX_VALUE之间 → 正常返回int - 超出范围 → 明确抛
ArithmeticException,不掩盖问题
示例:
int i = Math.toIntExact(1234567890L); // ✅ 成功<br> int j = Math.toIntExact(3000000000L); // ❌ 抛 ArithmeticException
手动校验再转(适合需要自定义 fallback 的场景)
如果不想抛异常,而是想返回默认值或记录告警,可显式判断:
- 先检查:
if (value >= Integer.MIN_VALUE && value - 再强转:
int result = (int) value; - 注意:必须用
Integer.MIN_VALUE这类常量,别硬写 -2147483648
避免常见错误写法:if (value <= Integer.MAX_VALUE && value >= 0)——漏了负数范围。
立即学习“Java免费学习笔记(深入)”;
别踩这些坑
不要 直接 (int) someLong,尤其当 long 来自外部输入、数据库或网络包时;
不要 先 Math.round() 或 Math.floor() 再强转,除非你真需要取整逻辑;
不要 在计算中间步骤里隐式降级,比如:int total = (int)(aLong * bLong);——乘法已在 long 层溢出,转 int 前就错了。
长期建议:从源头控类型
很多溢出问题其实源于设计阶段:
- ID、毫秒时间戳、累计计数等字段,Java 端统一用
long接收和运算,不轻易向下转 - DTO 和接口契约明确字段精度,避免前端传 “9223372036854775807” 字符串,后端用
Integer.parseInt()解析 - 高频累加场景(如 PV 统计),直接用
AtomicLong或BigInteger,绕过 int 边界


















