1. 方法定义
// 解析十进制无符号长整型
public static long parseUnsignedLong(String s) throws NumberFormatException
// 解析指定进制的无符号长整型
public static long parseUnsignedLong(String s, int radix) throws NumberFormatException
// 解析字符序列的无符号长整型(JDK9+)
public static long parseUnsignedLong(CharSequence s, int beginIndex, int endIndex, int radix)
2. 功能说明
核心功能:将字符串解析为 无符号长整型(0 到 18,446,744,073,709,551,615)
与有符号解析的区别: | 方法 | 支持范围 | 符号处理 | |---------------------|----------------------------------|------------------| |
parseLong
| -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 允许+
/-
| |parseUnsignedLong
| 0 到 18,446,744,073,709,551,615 | 禁止+
/-
|进制支持:2-36 进制(0-9, a-z 字符集)
3. 示例代码
public class UnsignedParseExample {
public static void main(String[] args) {
// 1. 解析十进制无符号数
long maxUnsigned = Long.parseUnsignedLong("18446744073709551615"); // 2^64-1
System.out.println(Long.toUnsignedString(maxUnsigned)); // 输出原始字符串
// 2. 解析十六进制无符号数
long hexValue = Long.parseUnsignedLong("FFFFFFFFFFFFFFFF", 16);
System.out.println(hexValue == -1); // true(有符号表示)
// 3. 解析超大值(超出有符号范围)
try {
Long.parseLong("9223372036854775808"); // 超出 long 最大值
} catch (NumberFormatException e) {
System.out.println("有符号解析失败: " + e.getMessage());
}
long unsignedBig = Long.parseUnsignedLong("9223372036854775808");
System.out.println("无符号解析成功: " + unsignedBig); // -9223372036854775808
// 4. 子序列解析(JDK9+)
CharSequence seq = "ID:1234567890";
long id = Long.parseUnsignedLong(seq, 3, 13, 10);
System.out.println("解析ID: " + id); // 1234567890
}
}
4. 关键特性
特性 | 说明 |
---|---|
无符号范围 | 0 到 18,446,744,073,709,551,615(即 0xFFFFFFFFFFFFFFFFL ) |
进制支持 | 支持 2-36 进制(字母不区分大小写) |
禁止符号 | 输入字符串不允许出现 + 或 - |
超大值处理 | 可解析大于 Long.MAX_VALUE (9.22e18) 的值 |
结果存储 | 返回 long 类型(高位为1的值将显示为负数) |
5. 使用场景
处理数据库/文件中的无符号值
// 读取 MySQL BIGINT UNSIGNED String dbValue = "18446744073709551615"; long id = Long.parseUnsignedLong(dbValue);
解析网络协议数据
// IPv6 地址解析 (16进制) String ipv6Part = "20010db80000"; long segment = Long.parseUnsignedLong(ipv6Part, 16);
处理加密哈希值
// SHA-256 片段解析 String hashFragment = "a3f4c2d1e0b9"; long hashPart = Long.parseUnsignedLong(hashFragment, 16);
6. 常见错误与解决方案
错误:包含符号字符
Long.parseUnsignedLong("-123"); // 抛出 NumberFormatException
解决:预处理去除符号
String input = getInput().trim(); if (input.startsWith("-") || input.startsWith("+")) { throw new IllegalArgumentException("无符号数不能包含符号"); }
错误:混淆有符号/无符号显示
long big = Long.parseUnsignedLong("18446744073709551615"); System.out.println(big); // 输出 -1(有符号视图)
解决:使用无符号转换方法
System.out.println(Long.toUnsignedString(big)); // 正确显示
错误:非法进制值
Long.parseUnsignedLong("1024", 1); // 进制<2
解决:检查进制范围
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { throw new IllegalArgumentException("无效进制: " + radix); }
7. 性能优化
预验证数字格式
// 快速检查是否为有效数字 boolean isValid = input.chars().allMatch(Character::isDigit);
重用解析结果
// 缓存频繁解析的值 private static final LongCache cache = new LongCache(); public static long parseCached(String s) { Long cached = cache.get(s); if (cached != null) return cached; return cache.put(s, Long.parseUnsignedLong(s)); }
避免重复解析
// 错误做法:多次解析相同字符串 if (Long.parseUnsignedLong(str) > threshold) { process(Long.parseUnsignedLong(str)); } // 正确做法:解析一次 long value = Long.parseUnsignedLong(str); if (value > threshold) { process(value); }
8. 无符号操作最佳实践
// 比较无符号值
boolean isLarger = Long.compareUnsigned(a, b) > 0;
// 无符号除法
long quotient = Long.divideUnsigned(dividend, divisor);
// 无符号转字符串
String hex = Long.toUnsignedString(value, 16);
总结
特性 | 说明 |
---|---|
核心用途 | 解析超出 Long.MAX_VALUE 或需要无符号语义的值 |
输入限制 | 禁止符号字符(+ /- ),仅限数字和字母(a-z) |
进制支持 | 2-36 进制(Character.MIN_RADIX 到 Character.MAX_RADIX ) |
结果处理 | 返回 long 类型,高位为1时显示负数(使用 toUnsignedString 正确显示) |
超大值处理 | 可处理最大 18,446,744,073,709,551,615 (264-1) |
JDK9+ 增强 | 支持 CharSequence 子序列解析 |
使用原则:
- 处理网络协议、数据库无符号字段或加密数据时优先使用
- 输入必须严格无符号(提前验证)
- 显示结果使用
Long.toUnsignedString()
- 比较/运算使用无符号工具方法(
compareUnsigned
,divideUnsigned
等)
性能对比(纳秒/操作):
parseUnsignedLong("123") : 15 ns
parseLong("123") : 12 ns
parseUnsignedLong(16进制字符串): 20 ns