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 |
对 null 的 Long 调用 .longValue() 或参与运算 |
使用前判空或用 Optional<Long> |
NumberFormatException |
解析非法字符串如 "abc" 、"12.3" |
使用 try-catch 包裹 parseLong |
== 比较对象 |
误用 == 比较 Long 对象引用 |
改用 .equals() 或 compareTo() |
溢出未检测 | Long.parseLong("9999999999999999999") 超出范围 |
使用 Math.addExact() 等精确方法或手动校验 |
构造函数过时 | 使用 new Long(123) |
改用 Long.valueOf(123) |
⚠️ 四、注意事项
缓存机制:
Long.valueOf(long)
在-128
到127
范围内返回缓存对象,提高性能。- 超出此范围每次返回新对象。
null 安全性:
Long
可为null
,而long
不能。在数据库映射、JSON 反序列化中常见。
自动拆箱风险:
Long l = null; long x = l; // 运行时抛出 NullPointerException
线程安全:
Long
对象本身是不可变的,因此是线程安全的。
序列化支持:
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() |
进制支持 | toBinaryString 、toHexString 、parseLong(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 开发中处理大整数、解析字符串、与数据库交互的基础技能。正确使用,可避免 NullPointerException
、NumberFormatException
等常见问题,提升代码健壮性与性能。