为什么我的类的序列化大小更大,然后是它的变量之和

时间:2017-07-25 09:26:00

标签: java serialization byte

我有一个简单的Java类:

public void go() throws FileNotFoundException {
    // some data source
    Collection<Record> db = Arrays.asList( new Record("01-01-2017", "Oracle", "1024", "0", "24"),
                                            new Record("02-02-2017", "Google", "2048", "32", "0"),
                                            new Record("03-03-2017", "Microsoft", "512", "16", "0"));

    // get output file
    File out = getOutputFile();
    PdfDocument pdfDocument = new PdfDocument(new PdfWriter(out));
    Document layoutDocument = new Document(pdfDocument);

    // set up table
    Table table = new Table(UnitValue.createPercentArray(new float[]{10f,20f,10f,10f,10f}));

    // add header
    table.addCell(new Cell().add(new Paragraph("Date")));
    table.addCell(new Cell().add(new Paragraph("Vendor")));
    table.addCell(new Cell().add(new Paragraph("Total")));
    table.addCell(new Cell().add(new Paragraph("Balance")));
    table.addCell(new Cell().add(new Paragraph("Rebate")));

    // iterate over records
    for(Record r : db)
    {
        table.addCell(new Cell().add(new Paragraph(r.date.toString())));
        table.addCell(new Cell().add(new Paragraph(r.vendor)));
        table.addCell(new Cell().add(new Paragraph(r.total + "")));
        table.addCell(new Cell().add(new Paragraph(r.balance + "")));
        table.addCell(new Cell().add(new Paragraph(r.rebate + "")));
    }

    // add table to document
    layoutDocument.add(table);

    // close
    layoutDocument.close();
}

由于int是4个字节,而一个字节是一个字节,这个类不应该需要5个字节吗?

但是当我序列化它并找到字节数组的长度时,我得到了59,

为什么会这样?

此外,我正在使用this将我的对象转换为字节数组。

3 个答案:

答案 0 :(得分:3)

简单:Java序列化不仅仅是字段值。请参阅相应的grammar规范。

你注意到例如serialVersionUID?这也必须进入二进制数据。当然 - 完整的类名(绝对 - 包括包)。

请记住:我们的想法是,您可以将序列化任意(可序列化)对象转换为字节流。 反序列化时,不要在这样的字节流中指定所有对象的类型!

换句话说:这些字节必须包含 all 恢复包含的对象实例所需的信息。因此,您需要完整的班级名称;如果存在,则使用该servialVersionUID进行一致性检查。

答案 1 :(得分:0)

因为序列化支持模式演变。也就是说,即使对象的定义已经改变,也可以反序列化对象。这对于允许长期存储序列化对象是必要的。

要启用此功能,序列化流会对有关序列化对象结构的元数据进行编码。此信息每个流只写一次,即如果流包含同一类的许多对象,则类元数据只写一次。

对于支持多态的序列化(您可以发送接收者期望的任何子类型的对象),此元数据还包括该类的完全限定名称。

为了提醒您数据结构的不兼容更改,元数据还包含类定义的校验和(serialVersionUID)。

请注意,架构演变是任何序列化协议的一个非常标准的功能。例如,JSON和XML为每个被编组的对象写入字段名称:

{Byte:0,id:42}

(14字节)

<SimpleClass><Byte>0</Byte><id>42</id></SimpleClass>

(62字节)

答案 2 :(得分:0)

因为为类序列化的数据不仅仅包含字段值。具体做法是:

  1. 一个类型字。
  2. 类描述符或向后引用一个。
  3. 所有Seri​​alizable基类的序列化信息。
  4. 每个序列化字段的名称。
  5. 其值,前面是另一个类型字。
  6. 至少。