[英]Array of Primitive Smaller than Primitive for ObjectOutputStream
我有一个函数,它接收一个对象并将其转换为字节数组:
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
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个字节。
对于其他对象(如装箱的基元),它使用更多的空间,因为它必须存储更多的元信息。 它必须存储对象的类型,并且必须为每个成员存储相同的信息-因此,它有点递归。
如果您真的想了解详细情况,建议阅读ObjectOutputStream
的源代码 。
这是因为Java对数组使用了不同的编码,效率更高。 如果序列化Byte
,它会写到您有一个对象(该对象稍后可能会引用,因此它记录一个id),该对象具有一个类java.lang.Byte
(该对象又具有一个id),该对象具有父类java.lang.Number
(也具有ID),其中没有字段,Byte具有一个称为“值”(是带有ID的字符串)的字段,而字节的值仅使用一个字节。
byte []的内部名称为[B
,它没有字段的父项,因此它短得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.