java二进制序列化流中基本类型以固定字节数、大端序原始二进制形式写入,无类型标识:boolean占1字节(0x00/0x01),byte/char/short/int/long/float/double分别占1/2/2/4/8/4/8字节,严格按写入顺序读取。

Java二进制序列化流(如ObjectOutputStream写入的.ser文件或网络传输的字节流)中,8种基本数据类型不是以“对象”形式存在,而是直接按JVM规范定义的固定字节数和编码规则写入原始二进制序列。这种设计保证了跨平台、跨JVM版本的可读性与一致性。
基本数据类型在序列化流中对应固定字节长度
每种类型在流中占用的字节数与其内存大小严格一致,且采用大端序(Big-Endian) 编码,不依赖宿主机字节序:
-
boolean:实际不单独占固定字节——序列化时不作为独立类型写入。它必须封装在对象(如Boolean)中,或作为字段被writeBoolean()方法写入,此时用 1个字节 表示(0x00→false,0x01→true)。 -
byte:1字节,原值直接写入(-128 ~ 127 的补码表示)。 -
char:2字节,UTF-16BE 编码(高位在前),例如'A'→0x0041。 -
short:2字节,有符号大端补码,例如-1→0xFFFF。 -
int:4字节,有符号大端补码,例如256→0x00000100。 -
long:8字节,有符号大端补码,例如1L→0x0000000000000001。 -
float:4字节,IEEE 754 单精度浮点(大端),例如1.0f→0x3F800000。 -
double:8字节,IEEE 754 双精度浮点(大端),例如1.0d→0x3FF0000000000000。
序列化流中的“标记”本质是协议约定,不是元数据标签
这些类型没有额外的类型标识字节(type tag) —— 它们的“标记”隐含在调用顺序和上下文中。例如:
out.writeBoolean(true); // 写入 1 字节:0x01
out.writeByte(127); // 写入 1 字节:0x7F
out.writeChar('中'); // 写入 2 字节:0x4E2D(UTF-16BE)
out.writeInt(1000); // 写入 4 字节:0x000003E8
解序列化时(ObjectInputStream),你必须严格按写出顺序调用对应读方法:readBoolean() → readByte() → readChar() → readInt()。
如果错位(比如用readInt()读writeByte()写的数据),就会解析出错误数值——因为流里只有原始字节,没有类型头。
注意几个关键细节
-
boolean在原始流中没有专用字节格式;DataOutput接口定义的writeBoolean()只是语义约定,底层仍是1字节整数编码。 -
char是无符号16位,但序列化仍用2字节大端补码形式(值域 0–65535,高位永远为0,所以等价于无符号)。 -
float/double的字节布局完全遵循 IEEE 754 标准,与平台无关;但某些老旧嵌入式JVM可能不支持非规约数(denormal),需避免依赖极端值。 - 所有基本类型写入不带长度前缀、不带类型ID,这是和
String或对象引用(含类描述符)的根本区别。
实际用途提示
当你用DataOutputStream手动构造协议(如网络通信、文件存储),应明确约定字段顺序和类型,例如:
[flag:1][id:4][name_len:4][name:utf-8 bytes][price:8]
其中 flag 是 boolean(1字节)、id 是 int(4字节)、price 是 double(8字节)——每个位置的字节数和解释方式都由协议硬性规定。
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











