HOWTO · Java

Java 中 long 和 int 数据类型的区别

这篇文章解释了 Java 中 long 和 int 数据类型的区别

本页内容

当程序预期处理的数值不会超出 int 的范围时,使用 int;数值可能更大时,选择 long。两者都是有符号基本整数类型。它们的包装类 Integer 和 Long 是对象,适用于要求使用引用类型的 API 和集合。下文将比较它们的取值范围、字面量语法,以及包装类的适用场景。

如何选择 Java 的 int 和 long

int 占 32 位,可表示从 -2,147,483,648 到 2,147,483,647 的值。long 占 64 位,可表示从 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 的值。应根据数据的预期范围选择类型;仅凭类型名称,并不能保证每次算术运算的结果都在范围内。

类型 位数 最小值 最大值
int 32 位 -2,147,483,648 2,147,483,647
long 64 位 -9,223,372,036,854,775,808 9,223,372,036,854,775,807

不带后缀的十进制整数文字,只要数值在 int 范围内,通常就会被视为 int。在文字末尾加上 L 可将其指定为 long,尤其是数值超出 int 范围时。建议使用大写 L,这样更容易与数字 1 区分。例如,long population = 9_000_000_000L; 使用了有效的 long 文字。下划线仅用于提高可读性,不会改变数值。

运行下面的示例,比较一个 int 值和一个 long 值。代码块中的可见标签保持英文,因为该示例按原样保留。

本节中的代码以及显示的标签或输出仍为英文。

public class IntVsLongExample {
    public static void main(String[] args) {
        int count = 120;
        long total = 9_000_000_000L;
        System.out.println("count: " + count);
        System.out.println("total: " + total);
    }
}
count: 120
total: 9000000000

要比较编译期行为,int tooLarge = 2147483648; 是无法编译的:这个十进制文字超出了 int 的范围,也没有标记为 long。应改为 long value = 2147483648L;。编译器会在程序运行前拒绝第一条声明,因此不会产生运行时输出。还要注意,除非某个操作数或强制转换使运算采用 long,否则 int 表达式会以 int 进行求值;如果结果已经溢出,再将它赋给 long 也无法恢复丢失的数值。

使用 Integer 和 Long 包装类

Integer 包装 int,Long 包装 long。Java 可通过自动装箱和自动拆箱在基本类型与对应包装类型之间转换。例如,Integer score = 42; 会将基本类型值装箱,而 int recordedScore = score; 则会将其拆箱。如果显式写出转换过程更易于理解,也可以使用 intValue() 和 longValue() 方法。

当 API 要求使用对象时,包装类就很有用。例如,List<Integer> 这样的泛型集合不能将基本类型用作类型参数,因此放入其中的值会被装箱。如果需要以对象形式表示 long,例如用于 List<Long>,就选择 Long。对于普通的局部算术运算,基本类型通常更简单;仅仅为了调用转换方法或实用方法,并不需要使用包装类。

包装后数值的范围不会改变:Integer 保存 int 值,Long 保存 long 值。包装类不会让数值超出其底层基本类型所能表示的范围。无论将 long 文字赋给 long 变量,还是装箱到 Long 中,都要使用 L 后缀。

基本类型与包装对象有何不同

基本类型变量保存该基本类型的值。包装类型变量则持有包装对象的引用,或者为 null。这才是编程时有用的区别;把包装对象简单描述为指向数值存储位置的指针,是不准确的物理内存模型,也无助于选择类型。

基本类型不能是 null。引用变量(例如 Integer optionalCount = null;)可以表示值缺失;当 API 或数据模型需要区分“未提供”和数值零时,这种表示方式很有用。使用该值前必须先检查是否为 null。如果 Java 对值为 null 的 Integer 或 Long 进行拆箱,就会抛出 NullPointerException;只有确认引用中存在对象后,才能进行拆箱。

简而言之,应根据所需数值范围选择 int 或 long;当基于对象的 API、集合或可空值需要包装类型时,再使用 Integer 或 Long。这样可以清楚地区分算术运算与缺失值的表示方式。