Java中字符串与整数的二进制表示差异及序列化类型识别问题
Java整数二进制转换规则与序列化类型判定
一、Java中整数12的二进制转换规则
Java的整数类型属于有符号基本数值类型,底层统一采用补码存储,正整数的补码与原码完全一致,负整数需要做取反加1的补码转换,整数12是正整数,不同整数类型的转换结果如下:
byte类型(1字节/8位):二进制为00001100short类型(2字节/16位):高位补0填充,二进制为00000000 00001100int类型(Java默认整数类型,4字节/32位):高位补0填充,二进制为00000000 00000000 00000000 00001100long类型(8字节/64位):高位补0填充,二进制为00000000 00000000 00000000 00000000 00000000 00000000 00000000 00001100
二、二进制内容重合的可能性
确实存在字节内容重合的场景:比如int类型的整数12594(十六进制为0x3132),对应的二进制为00000000 00000000 00110001 00110010,其中最后两个字节和字符串"12"的ASCII编码字节完全一致。
三、Java序列化的类型判定逻辑
Java的原生序列化机制(基于Serializable接口)完全不会出现类型判定混淆的问题,原因是序列化后的字节流中除了实际数据内容,还携带了完整的类型元信息:
- 序列化输出流开头固定携带魔数
0xACED和序列化版本号,用于标识这是合法的Java序列化流 - 每个字段的类型都会提前写入流中:比如基本类型int会用标记
I标识,String类型会用全类名Ljava/lang/String;标识 - 不同类型的序列化结构不同:比如序列化String"12"时,流内结构为【String类型标记】+【字符串长度2】+【两个ASCII字节0x31、0x32】;序列化int类型的0x3132时,流内结构为【int类型标记】+【4个数据字节0x00、0x00、0x31、0x32】
- 反序列化时会先读取类型标识,再按照对应类型的解析规则读取后续的内容字节,不会仅靠数据字节本身判断类型。
内容的提问来源于stack exchange,提问作者RAHUL DEEP
相关产品推荐
相关产品推荐

