Java ObjectOutputStream的基元数组小于基元数组

Java ObjectOutputStream的基元数组小于基元数组,java,arrays,memory,serialization,memory-management,Java,Arrays,Memory,Serialization,Memory Management,我有一个函数,它接收一个对象并将其转换为一个字节数组: public static byte[] serialize(Object obj) throws IOException { try(ByteArrayOutputStream b = new ByteArrayOutputStream()){ try(ObjectOutputStream o = new ObjectOutputStream(b)){ o.writeObject(obj);

我有一个函数,它接收一个对象并将其转换为一个字节数组:

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);

}
这将产生:


这里发生了什么?为什么阵列更小?下面是一个

对象输出流
处理基元数组的方式与其他对象不同。您不是序列化原语,而是序列化之前装箱的对象,因此
int
变成
Integer
等等

对于数组,
ObjectOutputStream
只编写以下内容(我使用
double
作为示例)

在你的实验中观察到35字节

对于其他对象(如盒装原语),它使用更多的空间,因为它必须存储更多的元信息。它必须存储对象的类型,对于每个成员,它必须存储相同的信息——所以它有点递归地进行


如果您真的想详细了解发生了什么,我建议您阅读
ObjectOutputStream

的内容,这是因为Java对数组使用了不同的编码,更有效。如果您序列化一个
字节
,它会写下您有一个对象(稍后您可能会引用它,以便它记录一个id),该对象有一个类
java.lang.Byte
(它同样有一个id),它有一个父类
java.lang.Number
(也有一个id),它没有字段,而Byte有一个字段称为“value”(这是一个带有id的字符串),字节的值只使用一个字节

字节[]的内部名称为
[B
,它没有字段的父级,因此要短得多

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
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