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 = 12
与 int 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,如果是,它知道后面的数据是一个字符串,而不是一个整数或其他任何东西。
作为字符串的“12”的位表示是“00110001 00110010”,其中“00110001”表示 ASCII 值 49,即“1”,“00110010”表示 ASCII 值 50,即“2”。 这对于 String 来说看起来不错,但是如何将 12 的整数值转换为 Java 中的位? 如果两者相同那么Java序列化后到达目标后如何判断其数据类型?
整数不是 ASCII。数字的实际字符未存储在任何地方
int x = 12
与 int 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,如果是,它知道后面的数据是一个字符串,而不是一个整数或其他任何东西。