java.lang.Long 是 Java 中用于封装基本类型 long 的包装类(Wrapper Class),属于 Java 基本数据类型包装体系的一部分。它不仅提供了 long 类型的面向对象表示,还包含丰富的工具方法用于字符串转换、进制处理、比较、解析等操作。


📚 一、核心概念

1. 基本信息

  • 类名java.lang.Long
  • 所属包java.lang(自动导入)
  • 继承关系
    public final class Long extends Number implements Comparable<Long>
    
  • 不可变性Long不可变对象,一旦创建其值不能更改。
  • 默认值:在对象字段中未初始化时为 null(区别于基本类型 long 的默认值 0L)。

2. 数据范围

  • long 是 64 位有符号整数:
    • 最小值:Long.MIN_VALUE = -9,223,372,036,854,775,808(-2^63)
    • 最大值:Long.MAX_VALUE = 9,223,372,036,854,775,807(2^63 - 1)

3. 自动装箱与拆箱(Autoboxing/Unboxing)

从 Java 5 开始支持:

Long a = 100L;        // 自动装箱:long → Long
long b = a;           // 自动拆箱:Long → long

🛠️ 二、操作步骤(非常详细)

✅ 步骤 1:创建 Long 对象

方法 1:使用构造函数(已过时,不推荐)

@Deprecated(since="9")
Long l1 = new Long(123L);        // 不推荐
Long l2 = new Long("123");       // 字符串构造(也已过时)

⚠️ 注意:Long 的构造函数在 Java 9 中已标记为 @Deprecated,应避免使用。

方法 2:使用静态工厂方法 valueOf()(推荐)

Long l1 = Long.valueOf(123L);           // long → Long
Long l2 = Long.valueOf("123");          // String → Long
Long l3 = Long.valueOf("1FF", 16);      // 字符串 + 进制(十六进制)

// 示例:解析十进制、二进制、十六进制
Long bin = Long.valueOf("1010", 2);     // 二进制 → 10
Long hex = Long.valueOf("ABC", 16);     // 十六进制 → 2748

✅ 推荐理由:valueOf() 使用缓存机制(-128 到 127),性能更高。


✅ 步骤 2:将 Long 转换为基本类型 long

Long l = Long.valueOf(456L);
long primitive = l.longValue();         // 显式拆箱
long autoUnbox = l;                     // 自动拆箱(推荐简洁写法)

⚠️ 若 l == null,调用 .longValue() 或自动拆箱会抛出 NullPointerException


✅ 步骤 3:字符串 ↔ Long 相互转换

将字符串解析为 Long

try {
    Long l1 = Long.parseLong("123");         // 返回 long(基本类型)
    Long l2 = Long.valueOf("123");           // 返回 Long(对象)

    // 指定进制
    Long bin = Long.parseLong("1101", 2);    // 二进制 → 13
    Long hex = Long.parseLong("FF", 16);     // 十六进制 → 255

} catch (NumberFormatException e) {
    System.err.println("字符串格式错误:" + e.getMessage());
}

将 Long 转为字符串

Long l = 123L;
String s1 = l.toString();                  // "123"
String s2 = String.valueOf(l);             // 同上
String s3 = "" + l;                        // 隐式调用 toString()

// 指定进制输出
String binary = Long.toBinaryString(10);   // "1010"
String octal  = Long.toOctalString(10);    // "12"
String hex    = Long.toHexString(255);     // "ff"

✅ 步骤 4:比较两个 Long 值

方法 1:使用 compareTo()

Long a = 100L;
Long b = 200L;

int result = a.compareTo(b);
// result < 0 → a < b
// result = 0 → a == b
// result > 0 → a > b

方法 2:使用 equals()(注意自动拆箱陷阱)

Long a = 100L;
Long b = 100L;

System.out.println(a == b);        // false(对象引用不同,除非在 -128~127 缓存内)
System.out.println(a.equals(b));   // true(值相等)

// ❌ 错误比较:自动拆箱导致空指针
Long c = null;
// long x = c; // 抛出 NullPointerException

方法 3:使用 Long.compare(long x, long y)

int cmp = Long.compare(a, b);  // 返回 -1, 0, 1

✅ 步骤 5:进制转换与位操作

long num = 255;

// 转换为不同进制字符串
System.out.println(Long.toBinaryString(num));  // 11111111
System.out.println(Long.toOctalString(num));   // 377
System.out.println(Long.toHexString(num));     // ff

// 从字符串解析指定进制
long fromBin = Long.parseLong("1111", 2);      // 15
long fromHex = Long.decode("0xFF");            // 255(支持 0x, # 前缀)

// 位操作(常用)
long flipped = ~num;                           // 按位取反
long shifted = num << 2;                       // 左移 2 位

❌ 三、常见错误

错误 描述 修复方式
NullPointerException nullLong 调用 .longValue() 或参与运算 使用前判空或用 Optional<Long>
NumberFormatException 解析非法字符串如 "abc""12.3" 使用 try-catch 包裹 parseLong
== 比较对象 误用 == 比较 Long 对象引用 改用 .equals()compareTo()
溢出未检测 Long.parseLong("9999999999999999999") 超出范围 使用 Math.addExact() 等精确方法或手动校验
构造函数过时 使用 new Long(123) 改用 Long.valueOf(123)

⚠️ 四、注意事项

  1. 缓存机制

    • Long.valueOf(long)-128127 范围内返回缓存对象,提高性能。
    • 超出此范围每次返回新对象。
  2. null 安全性

    • Long 可为 null,而 long 不能。在数据库映射、JSON 反序列化中常见。
  3. 自动拆箱风险

    Long l = null;
    long x = l; // 运行时抛出 NullPointerException
    
  4. 线程安全

    • Long 对象本身是不可变的,因此是线程安全的。
  5. 序列化支持

    • Long 实现了 Serializable,可用于网络传输或持久化。

💡 五、使用技巧

技巧 说明
✅ 优先使用 valueOf() 性能更好,支持缓存
✅ 使用 Optional<Long> 防 null 函数式编程中推荐
✅ 用 compareTo() 替代减法比较 避免溢出:a - b > 0 可能溢出
✅ 使用 decode() 解析带前缀字符串 "0xFF", "#FF", "011"
✅ 用 parseUnsignedLong() 处理无符号 long Java 8+ 支持大于 Long.MAX_VALUE 的正数解析
// 示例:解析无符号 long(最大可达 2^64 - 1)
String unsignedStr = "18446744073709551615";
long unsigned = Long.parseUnsignedLong(unsignedStr);

🏆 六、最佳实践与性能优化

实践 说明
✅ 使用 Long.valueOf() 创建实例 避免构造函数,利用缓存
✅ 避免频繁装箱拆箱 在循环中尽量使用 long 而非 Long
✅ 在集合中谨慎使用 Long List<Long>long[] 占用更多内存和 GC 压力
✅ 使用 Long.compare() 进行安全比较 a - b 更安全
✅ 使用 Objects.equals(a, b) 安全比较 Long 自动处理 null
✅ 高频计算使用原生 long 提升性能,减少 GC
✅ 使用 LongAdder / LongAccumulator 替代 AtomicLong(高并发场景) 分段累加,减少竞争

📊 性能对比示例

// 慢:频繁装箱
List<Long> list = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
    list.add(Long.valueOf(i)); // 创建对象,GC 压力大
}

// 快:使用原生数组
long[] arr = new long[1000000];
for (int i = 0; i < 1000000; i++) {
    arr[i] = i;
}

📝 七、总结

项目 内容
核心作用 包装 long 类型,支持对象操作、泛型、null 值
创建方式 推荐 Long.valueOf(x),避免 new Long()
字符串转换 parseLong() / valueOf(String) + try-catch
比较方法 compareTo()equals()Long.compare()
进制支持 toBinaryStringtoHexStringparseLong(s, radix)
注意事项 null 安全、自动拆箱陷阱、缓存机制
最佳实践 少装箱、多用原生、缓存利用、null 防护
性能建议 循环/高频计算用 long;集合中权衡内存与功能

一句话掌握精髓

Long.valueOf() 创建,用 parseLong() 解析,用 .equals()compareTo() 比较,警惕 null 和自动拆箱,优先使用 long 提升性能。


📌 适用场景速查

场景 推荐用法
JSON/数据库字段映射 Long(支持 null)
集合存储(如 List<Long> 可用,但注意性能
高频数学计算 使用 long 原生类型
比较大小 Long.compare(a, b)
字符串转数字 Long.parseLong(str)valueOf(str)
无符号数处理 Long.parseUnsignedLong(str)(Java 8+)

掌握 Long 类,是 Java 开发中处理大整数、解析字符串、与数据库交互的基础技能。正确使用,可避免 NullPointerExceptionNumberFormatException 等常见问题,提升代码健壮性与性能。