杰瑞科技汇

Java中long和long有何区别?

  • long:是 Java 的原始数据类型(Primitive Type)
  • Long:是 long 对应的包装类(Wrapper Class)

下面我们从多个维度进行详细的对比。

Java中long和long有何区别?-图1
(图片来源网络,侵删)

核心区别对比表

特性 long (原始类型) Long (包装类)
类型 原始数据类型 引用类型 (Object)
默认值 0 null
用途 存储数值,用于计算 可以表示“无值”状态,用于泛型、集合、反射等
内存占用 固定大小 (8 bytes) 较大,包含对象头和值
可为 null
示例用法 long id = 12345L; Long id = null;Long id = 12345L;
自动装箱/拆箱 支持 支持
继承关系 - 继承自 Number 类,实现了 Comparable 接口

详细解释

long - 原始数据类型

long 是 Java 八种原始数据类型之一,专门用于存储整数。

  • 本质:它只是一个值的容器,直接存储在内存的栈(Stack)上。
  • 大小:占用 64 位(8 字节)的内存空间。
  • 范围:可以表示的数值范围是 -2^632^63-1 (即 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807)。
  • 默认值:当一个 long 类型的成员变量没有被初始化时,它的默认值是 0
  • 不能为 nulllong 类型必须有一个有效的整数值,不能是 null,如果你尝试将 null 赋值给一个 long 变量,编译器会报错。

示例:

public class PrimitiveLongExample {
    // 成员变量,默认值为 0
    long defaultLong;
    public static void main(String[] args) {
        // 局部变量必须显式初始化
        long myLong = 10000000000L; // 注意:字面量需要加 L 或 l 后缀
        System.out.println("myLong 的值: " + myLong);
        System.out.println("defaultLong 的值: " + defaultLong); // 输出 0
        // 以下代码会编译错误!
        // long anotherLong = null; 
    }
}

Long - 包装类

Long 是一个类,属于 java.lang 包,它被称为 long 的“包装类”,因为它将一个 long 原始类型的值“包装”进了一个 Long 对象中。

  • 本质:它是一个对象,存储在堆(Heap)上,对象中包含一个 long 类型的字段来存储实际的值。
  • 大小:比 long 原始类型大得多,因为它包含了对象头(如哈希码、锁信息等)。
  • 可以为 nullLong 对象可以是 null,这非常有用,可以用来表示“没有值”、“未知值”或“缺失值”。
  • 提供实用方法Long 类提供了很多有用的静态方法,
    • Long.parseLong(String s): 将字符串解析为 long 值。
    • Long.valueOf(long l): 将 long �量转换为 Long 对象。
    • Long.toString(long l): 将 long 值转换为字符串。

示例:

Java中long和long有何区别?-图2
(图片来源网络,侵删)
public class LongWrapperExample {
    // 成员变量,默认值为 null
    Long nullableLong;
    public static void main(String[] args) {
        // 局部变量必须显式初始化
        Long myLongObj = 10000000000L; // 这里发生了自动装箱
        System.out.println("myLongObj 的值: " + myLongObj);
        // 可以是 null
        Long anotherLongObj = null;
        System.out.println("anotherLongObj 的值: " + anotherLongObj); // 输出 null
        System.out.println("nullableLong 的值: " + nullableLong); // 输出 null
        // 使用 Long 类的静态方法
        String numStr = "123456";
        long parsedLong = Long.parseLong(numStr);
        System.out.println("解析后的 long 值: " + parsedLong);
    }
}

自动装箱与拆箱

为了方便在原始类型和包装类之间转换,Java 5 引入了自动装箱自动拆箱机制。

  • 自动装箱:当 Java 需要将一个 long 值赋给一个 Long 引用时,会自动将其转换为一个 Long 对象。

    Long myLong = 10L; // 编译器自动将其转换为: Long myLong = Long.valueOf(10L);
  • 自动拆箱:当 Java 需要将一个 Long 对象用在需要 long 值的地方(如数学运算)时,会自动将其拆箱为 long 值。

    Long a = 10L;
    long b = a + 5; // 编译器自动将其转换为: long b = a.longValue() + 5;

⚠️ 自动装箱/拆箱的陷阱(NPE - NullPointerException)

Java中long和long有何区别?-图3
(图片来源网络,侵删)

自动拆箱时,Long 对象是 null,程序会抛出 NullPointerException

Long count = null;
// 以下代码会抛出 NullPointerException
int total = count + 1; // 因为 count 是 null,无法调用 .longValue() 方法

何时使用 long,何时使用 Long

这是一个非常实际的问题,选择哪个取决于你的具体需求。

使用 long 的情况:

  1. 基本计算:当你只需要进行纯粹的数值计算,不关心“空值”概念时,这是最常见的情况。

    long sum = 0;
    for (int i = 0; i < 1000; i++) {
        sum += i;
    }
  2. 性能要求高:在性能极其敏感的循环或算法中,使用原始类型可以避免自动装箱/拆箱带来的开销,减少内存占用(因为对象在堆上,GC 会回收)。

  3. 数组:当你需要存储大量数值时,使用 long[]Long[] 更节省内存。

使用 Long 的情况:

  1. 需要表示“空”或“缺失”:这是使用 Long 最重要、最正当的理由,数据库中的字段可能为 NULL,对应的 Java 实体类字段就应该用 Long

    public class User {
        private Long id; // 用户ID可能不存在,所以用 Long
        private String name; // name 必须存在,用 String(String 本身可以为 null)
        // getters and setters...
    }
  2. 泛型:Java 的泛型(如 List<T>)不能使用原始类型,如果你需要一个 long 类型的列表,你必须使用 Long

    // 错误用法
    // List<long> ids = new ArrayList<>();
    // 正确用法
    List<Long> ids = new ArrayList<>();
    ids.add(1L);
    ids.add(null); // 可以添加 null
  3. 集合框架HashMapHashSet 等集合的键或值如果是 long 类型,必须使用 Long

    Map<Long, String> userMap = new HashMap<>();
    userMap.put(1001L, "Alice");
  4. 反射和 API 调用:很多 Java API(如反射、框架)的方法参数或返回值是 Object 类型,当你需要处理 long 时,必须使用 Long


场景 推荐类型 理由
简单数学运算、循环计数器 long 性能更高,内存开销小
数组存储大量数值 long[] Long[] 更节省内存
数据库字段可为 NULL Long 可以准确映射数据库的 NULL 值
需要表示“无值”或“未知” Long null 是一个完美的语义表达
使用泛型(如 List<T> Long 泛型不支持原始类型
作为 Map 的键或值 Long Map 的键值对必须是对象

记住这个核心原则:如果你需要一个单纯的数值,用 long;如果你需要一个可能为“空”的数值,或者需要一个对象,就用 Long

分享:
扫描分享到社交APP
上一篇
下一篇