Long.toUnsignedString(long i)
是 Java 8 引入的一个重要方法,用于将 long
类型的值以无符号十进制字符串的形式输出。它解决了传统有符号 long
在表示大正数时的局限性。
📚 一、为什么需要 toUnsignedString()
?
Java 的 long
是 64 位有符号整数,范围是:
- 有符号:
-2^63
到2^63 - 1
(即-9,223,372,036,854,775,808
到9,223,372,036,854,775,807
)
但如果我们想把 long
当作无符号 64 位整数使用,它的范围应该是:
- 无符号:
0
到2^64 - 1
(即0
到18,446,744,073,709,551,615
)
❌ 问题:
如果你有一个接近或超过Long.MAX_VALUE
的“无符号”值(比如0xFFFFFFFFFFFFFFFFL
),用Long.toString()
会显示为负数!
long maxUnsigned = 0xFFFFFFFFFFFFFFFFL; // 实际是 -1(有符号)
System.out.println(Long.toString(maxUnsigned)); // 输出: -1
✅ 解决方案:使用 Long.toUnsignedString()
正确显示其“无符号”值。
📌 二、方法定义
1. Long.toUnsignedString(long i)
public static String toUnsignedString(long i)
- 功能:将
long
值作为 无符号 64 位整数 转换为十进制字符串。 - 参数:
i
- 要转换的long
值 - 返回值:表示无符号值的十进制字符串
- 范围:
0
到18,446,744,073,709,551,615
2. Long.toUnsignedString(long i, int radix)
(扩展)
public static String toUnsignedString(long i, int radix)
- 功能:以指定进制(radix)将
long
作为无符号数转换为字符串。 - radix 范围:2 到 36(默认 10)
💡 三、示例代码
示例 1:基本使用(十进制)
public class ToUnsignedStringExample {
public static void main(String[] args) {
// 最大无符号 long 值:0xFFFFFFFFFFFFFFFF
long maxValue = 0xFFFFFFFFFFFFFFFFL; // 有符号值为 -1
System.out.println("有符号 toString(): " + Long.toString(maxValue));
// 输出: -1
System.out.println("无符号 toUnsignedString(): " + Long.toUnsignedString(maxValue));
// 输出: 18446744073709551615
// 其他示例
long val = 0x8000000000000000L; // 有符号为负,无符号为大正数
System.out.println(Long.toUnsignedString(val));
// 输出: 9223372036854775808
}
}
示例 2:指定进制输出
long x = 0x123456789ABCDEF0L;
// 无符号二进制
System.out.println(Long.toUnsignedString(x, 2));
// 输出: 1001000110100010101100111100010011010101111001101111011110000
// 无符号十六进制(注意:不是 toHexString)
System.out.println(Long.toUnsignedString(x, 16));
// 输出: 123456789abcdef0
// 无符号八进制
System.out.println(Long.toUnsignedString(x, 8));
// 输出: 22150515621257175760
⚠️ 注意:
Long.toHexString(x)
仍按有符号处理,负数会显示补码,但toUnsignedString(x, 16)
保证正确输出。
🔄 四、对比:toString()
vs toUnsignedString()
值(十六进制) | 有符号值 | Long.toString() |
Long.toUnsignedString() |
---|---|---|---|
0x7FFFFFFFFFFFFFFF |
9223372036854775807 | 9223372036854775807 | 9223372036854775807 |
0x8000000000000000 |
-9223372036854775808 | -9223372036854775808 | 9223372036854775808 |
0xFFFFFFFFFFFFFFFF |
-1 | -1 | 18446744073709551615 |
✅ 只有
toUnsignedString()
能正确表示完整的 64 位无符号范围。
🛠️ 五、使用技巧
1. 与 parseUnsignedLong()
配合使用
// 编码:long → 无符号字符串
String str = Long.toUnsignedString(0xFFFFFFFFFFFFFFFFL);
// str = "18446744073709551615"
// 解码:字符串 → long(作为无符号解析)
long parsed = Long.parseUnsignedLong(str);
System.out.println(parsed == 0xFFFFFFFFFFFFFFFFL); // true
2. 输出固定宽度(补零)
String unsigned = Long.toUnsignedString(x, 16);
// 补前导零到 16 位
String padded = String.format("%16s", unsigned).replace(' ', '0');
System.out.println(padded); // 如: 0000000012345678
3. 用于 UUID 或哈希值输出
// 模拟高位 long 的 UUID 部分
long highBits = 0x123456789ABCDEF0L;
String hex = Long.toUnsignedString(highBits, 16);
System.out.println("High: " + hex); // 123456789abcdef0
⚠️ 六、注意事项
Java 8+ 才支持:
toUnsignedString()
是 Java 8 新增方法,低版本不支持。返回的是
String
,不是Long
对象:
它是工具方法,不改变原始值。与
toBinaryString
/toOctalString
/toHexString
的区别:
这些方法没有无符号版本,它们对负数仍按补码输出,但不会加负号。而toUnsignedString(radix)
明确表示“无符号解释”。性能:
内部使用高效算法,性能良好,适合日志、调试输出。
❌ 七、常见错误
错误 | 说明 | 修复方式 |
---|---|---|
误用 toString() 显示大数 |
负数显示为 -1 等 |
改用 toUnsignedString() |
认为 toHexString() 是无符号 |
toHexString(-1) 输出 ffffffffffffffff ,但语义不明确 |
使用 toUnsignedString(x, 16) 更清晰 |
Java 7 及以下使用 | 编译错误 | 升级 JDK 或手动实现 |
🏆 八、最佳实践
场景 | 推荐方法 |
---|---|
显示可能为“无符号”的 long 值 |
✅ Long.toUnsignedString(x) |
解析无符号字符串 | ✅ Long.parseUnsignedLong(s) |
输出二进制/八进制/十六进制无符号值 | ✅ Long.toUnsignedString(x, radix) |
日常有符号数值输出 | Long.toString(x) 或 String.valueOf(x) |
高性能位操作 | 结合 rotateLeft 、bitCount 等 |
📝 九、总结
项目 | 内容 |
---|---|
核心功能 | 将 long 作为 无符号 64 位整数 转为字符串 |
解决痛点 | 正确显示 0x8000... 到 0xFFFF... 范围的大正数 |
关键方法 | Long.toUnsignedString(long i) 和 Long.toUnsignedString(long i, int radix) |
典型应用 | 位运算结果输出、哈希值、UUID、网络协议、加密算法 |
注意事项 | Java 8+,与 parseUnsignedLong 配对使用 |
性能 | 高效,适合调试和日志输出 |
推荐度 | ✅ 在处理“大正数”或“位模式”时必须使用 |
✅ 一句话掌握:
当你需要把
long
当作 0 到 18,446,744,073,709,551,615 的无符号数显示时,使用Long.toUnsignedString()
,避免负数误解。