Java 中数字字符串与整数的位表示

Bits representation of number String vs Integer in Java

作为字符串的“12”的位表示是“00110001 00110010”,其中“00110001”表示 ASCII 值 49,即“1”,“00110010”表示 ASCII 值 50,即“2”。 这对于 String 来说看起来不错,但是如何将 12 的整数值转换为 Java 中的位? 如果两者相同那么Java序列化后到达目标后如何判断其数据类型?

整数不是 ASCII。数字的实际字符未存储在任何地方

int x = 12int x = 0b1100

相同

不清楚您指的是什么序列化格式(但是,例如,Protobuf 会比 Java 默认的 ObjectInputStream 更好)或者您有什么具体的错误。序列化框架本身应该在位位置对字段边界进行编码,例如 - https://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html

ASCII is 字符编码标准,它将字符映射到代码点。

'1'是一个字符,'2'是一个字符,'a'是一个字符,'?'也是一个字符..

然而,

12 是一个数字,即 映射到任何代码点。

您可以将整数转换为其二进制字符串表示形式:

int x = 12;
String bx = Integer.toBinaryString(x);

System.out.println(bx);

将打印 1100,即十进制的 12

Java 对象序列化通过写入额外的元数据来区分整数 12 和包含 (char)12 的字符串。

比如这里是ObjectOutputStream.writeString。如您所见,它写入一个常量字节 TC_STRING(恰好被定义为 (byte)0x74)以表示后面的数据是一个字符串:

private void writeString(String str, boolean unshared) throws IOException {
    handles.assign(unshared ? null : str);
    long utflen = bout.getUTFLength(str);
    if (utflen <= 0xFFFF) {
        bout.writeByte(TC_STRING);
        bout.writeUTF(str, utflen);
    } else {
        bout.writeByte(TC_LONGSTRING);
        bout.writeLongUTF(str, utflen);
    }
}

然后reader可以读取一个字节,检查它是否是TC_STRING,如果是,它知道后面的数据是一个字符串,而不是一个整数或其他任何东西。