ByteBuffer默认大端,可调用order()切换字节序;大端高位存低地址、小端低位存低地址;跨语言交互须统一字节序,否则解析错误。

ByteBuffer 的字节序直接决定多字节数据(如 int、short、float)在内存中如何被读写。同一个字节数组,用大端或小端解析,会得到完全不同的数值结果——这不是“错”,而是字节解释规则不同。
大端与小端的本质区别
核心就一句话:看低位字节放在哪。
- 大端(Big-Endian):高位字节存低地址,低位字节存高地址。符合人类阅读习惯(从左到右,从高到低),也是网络字节序(Network Byte Order)标准。
- 小端(Little-Endian):低位字节存低地址,高位字节存高地址。x86/ARM 等主流 CPU 原生采用,硬件访问更高效。
例如整数 0x12345678(4 字节):
- 大端内存布局(地址由低到高):
12 34 56 78 - 小端内存布局(地址由低到高):
78 56 34 12
ByteBuffer 默认是大端,但可自由切换
Java 中 ByteBuffer 默认使用 ByteOrder.BIG_ENDIAN,所有 putInt()、getInt() 等方法都按此规则操作。
切换字节序只需调用 .order(ByteOrder.LITTLE_ENDIAN),之后所有多字节读写均按新顺序执行:
- 创建后未显式设置 → 按大端解析
- 调用
order(ByteOrder.LITTLE_ENDIAN)→ 后续读写全部转为小端 - 切换不影响已写入的字节内容,只改变后续读写的解释方式
跨系统/跨语言交互时字节序必须对齐
Java 默认大端,但很多本地代码(C/C++)、Python(struct.unpack('i', b) 默认小端)、嵌入式设备或硬件协议可能默认小端。若不统一,解析结果必然出错。
- 比如 Python 写入
b'\x78\x56\x34\x12'(小端 int),Java 用默认大端读取 → 得到0x78563412(错误) - 正确做法:Java 端显式设为小端
buffer.order(LITTLE_ENDIAN).getInt()→ 得到0x12345678(正确) - 网络传输建议统一用大端(即保持默认),避免协商成本
如何判断当前 JVM 的原生字节序?
调用 ByteOrder.nativeOrder() 即可获取底层 CPU 实际使用的字节序:
-
ByteOrder.BIG_ENDIAN→ 如 PowerPC、旧 Mac 系统 -
ByteOrder.LITTLE_ENDIAN→ Intel/AMD x86、主流 ARM 设备(包括 Android 手机) - 注意:JVM 屏蔽了平台差异,
nativeOrder()只反映硬件能力,不强制 ByteBuffer 行为

















