我有一个函数,它接受一个对象并将其转换为字节数组:
public static byte[] serialize(Object obj) throws IOException {
try(ByteArrayOutputStream b = new ByteArrayOutputStream()){
try(ObjectOutputStream o = new ObjectOutputStream(b)){
o.writeObject(obj);
}
return b.toByteArray();
}
}
当我在基元类型上使用此函数时,输出最终大于同一基元的单例数组。
public static void main (String[] args) throws java.lang.Exception
{
System.out.format("byte single: %d, array: %d\n",
serialize((byte) 1).length, serialize(new byte[]{1}).length);
System.out.format("short single: %d, array: %d\n",
serialize((short) 1).length, serialize(new short[]{1}).length);
System.out.format("int single: %d, array: %d\n",
serialize((int) 1).length, serialize(new int[]{1}).length);
System.out.format("float single: %d, array: %d\n",
serialize((float) 1).length, serialize(new float[]{1}).length);
System.out.format("double single: %d, array: %d\n",
serialize((double) 1).length, serialize(new double[]{1}).length);
}
这会产生:
byte single: 75, array: 28 short single: 77, array: 29 int single: 81, array: 31 float single: 79, array: 31 double single: 84, array: 35
这里发生了什么?为什么数组更小?这是一个Ideone for the issue
最佳答案
ObjectOutputStream
处理原始数组的方式与其他对象不同。您不是序列化基元,而是序列化对象,因为它们在序列化之前被装箱,因此 int
变为 Integer
等。
对于数组,ObjectOutputStream
只需写入以下内容(我使用 double
作为示例)
1 byte // to mark it as array
22 bytes // for the class description
4 bytes // the length of the array
8 bytes // for the double (would be array.length * 8) is you have more elements
正如您在实验中观察到的那样,这相当于 35 个字节。
对于其他对象(例如装箱基元),它使用更多空间,因为它必须存储更多元信息。它必须存储对象的类型,并且对于每个成员,它必须存储相同的信息 - 所以它有点递归地进行。
如果您确实想详细了解发生了什么,我建议您阅读source code ObjectOutputStream
。
关于java - 小于 ObjectOutputStream 基元的基元数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35636186/