下面我将从核心方法、风险、最佳实践三个方面详细解释。

核心转换方法:强制类型转换
在 Java 中,long 是 64 位整数,而 int 是 32 位整数,要将一个 long 值存入 int 变量,你必须使用强制类型转换(也称为显式转换或窄化转换)。
语法如下:
long longValue = ...; int intValue = (int) longValue;
示例代码:
public class LongToIntExample {
public static void main(String[] args) {
// 情况一:在 int 范围内的 long 值,转换成功
long long1 = 12345L;
int int1 = (int) long1;
System.out.println("long1: " + long1 + " -> int1: " + int1); // 输出: 12345
// 情况二:超出 int 范围的 long 值,会发生数据丢失
long long2 = 2147483648L; // int 的最大值是 2147483647
int int2 = (int) long2;
System.out.println("long2: " + long2 + " -> int2: " + int2); // 输出: -2147483648 (发生了溢出)
// 情况三:负数的 long 值
long long3 = -12345L;
int int3 = (int) long3;
System.out.println("long3: " + long3 + " -> int3: " + int3); // 输出: -12345
}
}
主要风险:数据丢失和溢出
强制类型转换 int 时,Java 会直接截断 long 值的高 32 位,只保留低 32 位,这会导致两种主要问题:

a) 溢出
当 long 的值超出了 int 的表示范围时,就会发生算术溢出。
int的范围是: -2,147,483,648 到 2,147,483,647 (即-2^31到2^31 - 1)。long的值大于2,147,483,647,转换后的int值会从负数开始计算。long的值小于-2,147,483,648,转换后的int值会从正数开始计算。
示例:
long bigLong = 2147483648L; // 比 Integer.MAX_VALUE 大 1 int result = (int) bigLong; // 2147483648 的二进制表示是 10000000 00000000 00000000 00000000 // 截断后,int 的符号位为 1,表示负数。 // 其值为 -2147483648,即 Integer.MIN_VALUE System.out.println(result); // 输出: -2147483648
b) 精度丢失
long 的值本身在 int 的范围内,但由于它的字面量写法使用了 L 后缀,转换是安全的,但如果 long 的值包含了超出 int 范围的部分,那么高位的部分就会被“切掉”,导致精度丢失。
long longWithHighBits = 0xFFFF_FFFF_FFFFL; // 一个很大的数 int truncatedInt = (int) longWithHighBits; // 只保留了低 32 位,即 0xFFFFFFFF,其十进制值为 -1 System.out.println(truncatedInt); // 输出: -1
最佳实践和安全转换
直接进行强制转换是危险的,因为它会静默地失败(不会抛出异常),在实际开发中,你应该在转换前进行检查,以确保数据的安全性。
手动范围检查(推荐)
这是最常用且最清晰的方法,在转换前,检查 long 值是否在 int 的范围内。
public static long safeLongToInt(long longValue) {
// 检查是否在 int 的范围内
if (longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
// 处理溢出情况,
// 1. 抛出一个异常
throw new ArithmeticException("Long value is out of int range: " + longValue);
// 2. 返回一个默认值(如 Integer.MAX_VALUE 或 Integer.MIN_VALUE)
// return Integer.MAX_VALUE;
// 3. 或者记录日志并返回一个特殊值
}
return (int) longValue;
}
// 使用示例
public static void main(String[] args) {
try {
long value = 1234567890123L;
int safeInt = safeLongToInt(value);
System.out.println("转换成功: " + safeInt);
} catch (ArithmeticException e) {
System.err.println("转换失败: " + e.getMessage());
}
}
使用 Math 类进行边界检查
Java 的 Math 类提供了一些工具方法,可以简化边界检查。
long longValue = ...;
// 检查是否小于等于 Integer.MAX_VALUE 且大于等于 Integer.MIN_VALUE
if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
int intValue = (int) longValue;
// 安全使用 intValue
} else {
// 处理溢出情况
}
使用 NumberUtils (Apache Commons Lang / Spring)
如果你在使用像 Apache Commons Lang 或 Spring 这样的库,它们提供了非常方便的工具方法。
Apache Commons Lang:
// 添加依赖: org.apache.commons:commons-lang3
import org.apache.commons.lang3.math.NumberUtils;
long longValue = ...;
// 如果转换失败,返回 null
Integer intValue = NumberUtils.createInteger(String.valueOf(longValue));
// 或者使用更严格的转换方法
try {
intValue = NumberUtils.toInt(Long.toString(longValue));
} catch (NumberFormatException e) {
// 处理转换失败
}
| 方法 | 描述 | 优点 | 缺点 |
|---|---|---|---|
(int) longValue |
强制类型转换 | 语法简单,直接 | 不安全,会静默溢出,可能导致难以发现的 bug |
| 手动范围检查 | 在转换前判断 longValue 是否在 Integer 范围内 |
安全可控,逻辑清晰,可以自定义处理溢出的方式 | 需要手动编写代码 |
Math 类检查 |
使用 Math 类进行边界判断 |
代码简洁 | 和手动检查类似,只是写法不同 |
| 第三方库工具 | 使用如 NumberUtils 等工具类 |
代码简洁,功能强大 | 需要引入外部依赖 |
核心建议:
永远不要直接对一个可能超出
int范围的long值进行强制转换。 在转换前,务必进行范围检查,或者使用能够安全处理溢出的方法,以确保程序的健壮性。
