long 是一个 64 位整数,而 int 是一个 32 位整数。int 的表示范围是 -2,147,483,648 到 2,147,483,647(即 -2^31 到 2^31 - 1)。long 类型的值超出了这个范围,直接转换会导致数据截断,即高位数据丢失,得到一个错误的、无意义的 int 值。

下面我将介绍几种转换方法,并重点讲解如何处理数据溢出的问题。
强制类型转换(不处理溢出)
这是最直接、最快速的方法,但也是最危险的方法,因为它不进行任何溢出检查。
语法:
int targetInt = (int) sourceLong;
示例代码:

public class LongToIntExample {
public static void main(String[] args) {
// 情况1:long 值在 int 范围内
long longValue1 = 12345L;
int intValue1 = (int) longValue1;
System.out.println("long 值 " + longValue1 + " 转换为 int: " + intValue1); // 输出: 12345
// 情况2:long 值超出 int 范围(会发生数据截断)
long longValue2 = 2147483650L; // 比 Integer.MAX_VALUE (2147483647) 大
int intValue2 = (int) longValue2;
System.out.println("long 值 " + longValue2 + " 强制转换为 int: " + intValue2);
// 输出: -2147483646 (高位被截断,结果是一个负数)
// 情况3:long 值远小于 int 范围(同样会发生数据截断)
long longValue3 = -2147483650L; // 比 Integer.MIN_VALUE (-2147483648) 小
int intValue3 = (int) longValue3;
System.out.println("long 值 " + longValue3 + " 强制转换为 int: " + intValue3);
// 输出: 2147483646 (高位被截断,结果是一个正数)
}
}
- 优点:性能高,语法简单。
- 缺点:不安全,
long值超出int范围,会导致数据丢失,程序不会报错,但结果可能完全错误。 - 适用场景:当你100%确定
long的值永远不会超出int的表示范围时使用,这个long值本身就是从一个int变量转换过来的,或者它来自一个有明确范围限制的源。
使用 Math.toIntExact()(推荐,处理溢出)
如果你需要确保转换的安全性,即在转换前检查值是否在 int 范围内,可以使用 java.lang.Math 类中的 toIntExact() 方法。
语法:
int targetInt = Math.toIntExact(sourceLong);
行为:
long值在int范围内,它会成功转换并返回结果。long值超出int范围,它会抛出一个ArithmeticException异常,通知你发生了算术溢出。
示例代码:

public class LongToIntSafeExample {
public static void main(String[] args) {
// 情况1:long 值在 int 范围内
long longValue1 = 12345L;
try {
int intValue1 = Math.toIntExact(longValue1);
System.out.println("long 值 " + longValue1 + " 安全转换为 int: " + intValue1); // 输出: 12345
} catch (ArithmeticException e) {
System.out.println("转换失败: " + e.getMessage());
}
// 情况2:long 值超出 int 范围(会抛出异常)
long longValue2 = 2147483650L;
try {
int intValue2 = Math.toIntExact(longValue2);
System.out.println("long 值 " + longValue2 + " 安全转换为 int: " + intValue2);
} catch (ArithmeticException e) {
// 程序会执行到这里
System.out.println("转换失败: " + e.getMessage()); // 输出: 转换失败: integer overflow
}
}
}
- 优点:安全,能明确地捕获溢出错误,避免程序因错误的数据而继续运行。
- 缺点:如果发生溢出,会抛出异常,需要使用
try-catch块来处理,这会增加代码的复杂度。 - 适用场景:强烈推荐在大多数业务场景下使用,当你需要处理来自外部(如用户输入、文件读取、网络请求)的数据,或者无法完全确定
long值的范围时,这是最安全的选择。
手动检查范围(处理溢出)
如果你不想使用 Math.toIntExact() 或者想自定义溢出后的处理逻辑(给一个默认值而不是抛出异常),可以手动进行范围检查。
逻辑:
- 判断
long值是否大于Integer.MAX_VALUE。 - 判断
long值是否小于Integer.MIN_VALUE。 - 如果在范围内,则进行强制转换;如果不在范围内,则执行自定义逻辑(如返回默认值、抛出自定义异常等)。
示例代码:
public class LongToIntManualCheckExample {
public static void main(String[] args) {
long longValue = 2147483650L;
int intValue;
// 手动检查范围
if (longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
System.out.println("警告: long 值 " + longValue + " 超出 int 范围,将使用默认值 0");
intValue = 0; // 自定义处理逻辑,例如返回默认值
} else {
intValue = (int) longValue;
}
System.out.println("最终得到的 int 值为: " + intValue); // 输出: 0
}
}
- 优点:灵活性高,可以根据业务需求自定义溢出后的处理方式。
- 缺点:代码量比
Math.toIntExact()多,需要自己编写检查逻辑。 - 适用场景:当你需要特殊的溢出处理逻辑,而不是简单地抛出异常时。
总结与最佳实践
| 方法 | 语法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 强制转换 | (int) longValue |
性能高,语法简单 | 不安全,数据溢出时静默截断 | 100%确定 long 值在 int 范围内 |
Math.toIntExact() |
Math.toIntExact(longValue) |
安全,明确抛出溢出异常 | 需要处理 ArithmeticException |
推荐,处理不确定范围的 long 值 |
| 手动检查 | if/else 检查 |
灵活性高,可自定义处理逻辑 | 代码冗长,容易出错 | 需要特殊溢出处理逻辑的业务 |
核心建议:
- 优先使用
Math.toIntExact():在大多数情况下,这是最安全、最清晰的选择,它能帮助你及早发现潜在的数据问题。 - 仅在绝对安全时使用强制转换:代码中有一个
long变量,但你非常清楚它的来源和范围永远不会导致溢出。 - 避免在关键业务逻辑中使用不安全的强制转换:否则,一个微小的数据变化就可能导致程序产生严重且难以排查的 Bug。
