
本文详解如何将小端序编码的十六进制字符串(如 "c4d2")安全、准确地解析为对应的无符号 16 位整数(如 53956),避免 Java 原生 short 类型符号溢出问题。
本文详解如何将小端序编码的十六进制字符串(如 `"c4d2"`)安全、准确地解析为对应的无符号 16 位整数(如 `53956`),避免 java 原生 `short` 类型符号溢出问题。
在 Java 中,将十六进制字符串(如 "c4d2")解析为整数时,需特别注意字节序与数据类型的符号性。虽然该字符串表示的是一个 小端序(little-endian)编码的 16 位整数,其真实值为 53956(即 0xD2C4 十六进制,按小端排列为 0xC4 0xD2),但直接使用 ByteBuffer.getShort() 会返回有符号的 short(范围 -32768 到 32767),导致 0xC4D2 被解释为 -11580(即 short 的补码值),从而出错。
✅ 正确做法是:先将十六进制字符串解析为字节数组,再用 ByteBuffer 按小端序读取 short,最后通过 Short.toUnsignedInt() 将其无符号提升为 int:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.HexFormat;
public class HexToIntConverter {
public static int hexStringToUnsignedShort(String hex) {
// 确保长度为偶数(每个字节对应两个十六进制字符)
if (hex.length() % 2 != 0) {
throw new IllegalArgumentException("Hex string length must be even");
}
byte[] bytes = HexFormat.of().parseHex(hex);
if (bytes.length != 2) {
throw new IllegalArgumentException("Expected exactly 2 bytes for 16-bit integer");
}
int value = Short.toUnsignedInt(
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort()
);
return value;
}
public static void main(String[] args) {
String s = "c4d2";
int n = hexStringToUnsignedShort(s);
System.out.println(s + " -> " + n); // 输出:c4d2 -> 53956
}
}
? 关键要点说明:
-
HexFormat.of().parseHex("c4d2")正确解析为字节数组[-60, -46](即0xC4,0xD2的有符号字节表示); -
ByteBuffer.order(ByteOrder.LITTLE_ENDIAN)确保低位字节0xC4在前,高位字节0xD2在后,组合为0xD2C4; -
getShort()返回short值-11580(即0xD2C4的有符号解释),但Short.toUnsignedInt()将其无符号重解释为53956—— 这正是目标结果; - ⚠️ 注意:此方法仅适用于 恰好 2 字节(4 位十六进制字符) 的输入;若需支持 32 位(
int)或 64 位(long),应分别使用getInt()/getLong()并配合ByteOrder.LITTLE_ENDIAN,且无需额外无符号转换(因int/long本身足够容纳)。
总结:Java 中处理小端十六进制字符串转整数,核心在于 字节解析 → 小端序读取 → 无符号类型提升。切勿直接强转或依赖 Integer.parseInt(hex, 16)(它默认大端且忽略字节序),也无需绕道二进制拼接等非直观方式。使用 Short.toUnsignedInt() 是简洁、标准且零依赖的解决方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











