做协议解析或日志处理时经常碰到十六进制字符串,java 16进制转10进制这件事不用自己写乘 16 的循环,现成方法就有好几个,按数字大小选。

int 范围内用 Integer

int n = Integer.parseInt(hexStr, 16); 是用得最多的写法,第二个参数 16 表示按十六进制解析。注意传入的字符串不能带 0x 前缀、不能有空格,日志里常见的 0x1F 得先处理掉前缀再传进去。

反方向输出十六进制用 String hex = Integer.toHexString(n);,结果不带前缀,字母是小写,需要大写就自己 toUpperCase。

超过 int 范围换 BigInteger

十六进制一位对应 4 个二进制位,8 位十六进制正好是 32 位,贴着 int 的上限。位数更多的(比如 16 位十六进制的 64 位标识)用 BigInteger big = new BigInteger(hexStr, 16);,它不会溢出;Long.parseLong(hexStr, 16) 则能接住 16 位以内的十六进制。

负数是最大的坑

解析 FFFFFFFF 这种 8 个 F,parseInt 返回的是 -1 而不是 4294967295,因为按补码解释了。想要无符号的 4294967295,用 new BigInteger(hexStr, 16)。另外这套方法只处理整数,带小数点的十六进制得按位自己拆。

举个实际例子:色值 1A2B3C 这种十六进制颜色,拆成三段后每段用 parseInt 转十进制,就能得到 RGB 的三个分量;硬件文档里 0x4001 开头的寄存器地址,同样转成十进制好和手册对照。

如果字符串来自用户输入,转之前先做校验:看长度、只放行 0 到 9 和 a 到 f 这些字符,遇到非法字符 parseInt 会直接抛 NumberFormatException,提前拦一层省得炸在业务里。偶尔还要把十进制格式化回十六进制展示,String.format 配合 %08X 能输出固定位数、字母大写的结果。

总结成一句:一般业务数据 parseInt(str, 16) 够用;位数超过 8 位或者要无符号语义,直接上 BigInteger,别用 long 硬接,边界值容易翻车。