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. 使用场景

  1. 处理数据库/文件中的无符号值

    // 读取 MySQL BIGINT UNSIGNED
    String dbValue = "18446744073709551615";
    long id = Long.parseUnsignedLong(dbValue);
    
  2. 解析网络协议数据

    // IPv6 地址解析 (16进制)
    String ipv6Part = "20010db80000";
    long segment = Long.parseUnsignedLong(ipv6Part, 16);
    
  3. 处理加密哈希值

    // SHA-256 片段解析
    String hashFragment = "a3f4c2d1e0b9";
    long hashPart = Long.parseUnsignedLong(hashFragment, 16);
    

6. 常见错误与解决方案

  1. 错误:包含符号字符

    Long.parseUnsignedLong("-123"); // 抛出 NumberFormatException
    

    解决:预处理去除符号

    String input = getInput().trim();
    if (input.startsWith("-") || input.startsWith("+")) {
        throw new IllegalArgumentException("无符号数不能包含符号");
    }
    
  2. 错误:混淆有符号/无符号显示

    long big = Long.parseUnsignedLong("18446744073709551615");
    System.out.println(big); // 输出 -1(有符号视图)
    

    解决:使用无符号转换方法

    System.out.println(Long.toUnsignedString(big)); // 正确显示
    
  3. 错误:非法进制值

    Long.parseUnsignedLong("1024", 1); // 进制<2
    

    解决:检查进制范围

    if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
        throw new IllegalArgumentException("无效进制: " + radix);
    }
    

7. 性能优化

  1. 预验证数字格式

    // 快速检查是否为有效数字
    boolean isValid = input.chars().allMatch(Character::isDigit);
    
  2. 重用解析结果

    // 缓存频繁解析的值
    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));
    }
    
  3. 避免重复解析

    // 错误做法:多次解析相同字符串
    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_RADIXCharacter.MAX_RADIX
结果处理 返回 long 类型,高位为1时显示负数(使用 toUnsignedString 正确显示)
超大值处理 可处理最大 18,446,744,073,709,551,615 (264-1)
JDK9+ 增强 支持 CharSequence 子序列解析

使用原则

  1. 处理网络协议、数据库无符号字段或加密数据时优先使用
  2. 输入必须严格无符号(提前验证)
  3. 显示结果使用 Long.toUnsignedString()
  4. 比较/运算使用无符号工具方法(compareUnsigned, divideUnsigned等)

性能对比(纳秒/操作):

parseUnsignedLong("123")       : 15 ns
parseLong("123")               : 12 ns 
parseUnsignedLong(16进制字符串): 20 ns