
Java 中 Long.toHexString() 本身只做数值转小写十六进制字符串,不满足网络协议对流水号的常见要求(如固定长度、大写、带前缀/校验、线程安全等)。需在它基础上封装处理。
确保固定位数(补零)
协议通常要求流水号为定长(如 16 位或 20 位),而 toHexString() 输出无前导零。例如 Long.toHexString(0x1L) 得 "1",但协议可能需要 "0000000000000001"。
用 String.format("%016x", value) 补零并转小写 若需大写,用 "%016X"(X 大写) 避免手动拼接或 Integer.toHexString().padLeft()(Java 11+ 才有 padStart,且不推荐用于数值补零)
保证唯一性与单调递增(适用于序列号场景)
单纯用 System.currentTimeMillis() 或随机 long 转十六进制易冲突或乱序。协议常要求“时间相关 + 自增”或“分布式唯一”。
本地高并发下可用 AtomicLong 配合时间戳:如 (System.nanoTime() ,再转十六进制 更稳妥用 java.util.UUID.randomUUID().getMostSignificantBits() 截取后转,但不保证单调 若协议明确要求“毫秒级时间 + 序列”,建议组合 System.currentTimeMillis() 和原子计数器,并统一格式化为 16 进制字符串
适配协议约定格式(大小写、前缀、分隔符)
有些协议规定必须大写(如 HTTP/2 流 ID)、带 "0x" 前缀、或每 4 位加下划线(如 "ABCD_EF01_2345_6789")。
立即学习“Java免费学习笔记(深入)”;
大写直接用 String.format("%016X", value) 加前缀:"0x" + String.format("%016X", value) 分组显示(仅展示用,非传输):先得 16 位字符串,再用正则或循环每 4 字符插入 "_",但注意协议是否允许分隔符——多数二进制协议只接受纯十六进制字符
注意线程安全与性能边界
Long.toHexString() 本身是无状态、线程安全的,但如果你在外层加了计数器、时间戳缓存或格式化缓存,就需同步保障。
避免在高频生成逻辑中反复创建 StringBuilder 或调用 String.format(可考虑预编译或使用 ThreadLocal 缓存格式器) 若流水号需全局唯一且跨 JVM,Long 范围(±9.2×10¹⁸)虽大,但高并发下仍可能撞号——此时应改用 Snowflake 算法生成 long 再转十六进制 测试时验证边界值:如 Long.MAX_VALUE、0L、负数(协议一般不用负数,建议限定为 0L 到 Long.MAX_VALUE)

评论(0)