Java的序列化是如何工作的,什么时候应该使用它来代替其他一些持久性技术?

2022-09-01 02:29:48

我最近一直在尝试学习更多知识,并普遍测试Java在工作和个人项目中的序列化,我必须说,我对它的了解越多,我就越不喜欢它。这可能是由错误信息引起的,所以这就是为什么我向你们所有人询问这两件事:

1:在字节级别,序列化如何知道如何将序列化值与某个类进行匹配?

我在这里遇到的一个问题是,我用ArrayList做了一个小测试,其中包含值“一”,“二”,“三”。序列化后,字节数组需要78个字节,对于如此低的信息量(19 + 3 + 3 + 4字节)来说,这似乎非常多。当然,肯定会有一些开销,但这引出了我的第二个问题:

阿拉伯数字:序列化是否可以被视为持久化对象的好方法?现在显然,如果我使用一些自制的XML格式,持久性数据将是这样的

<object>
    <class="java.util.ArrayList">
    <!-- Object array inside Arraylist is called elementData -->
    <field name="elementData">
        <value>One</value>
        <value>Two</value>
        <value>Three</value>
    </field>
</object>

与一般的XML一样,它有点臃肿,需要138个字节(没有空格)。JSON中的相同内容可能是

{
    "java.util.ArrayList": {
        "elementData": [
            "one",
            "two",
            "three"
        ]
    }
}

这是75个字节,所以已经比Java的序列化略小。使用这些基于文本的格式,当然很明显,必须有一种方法将基本数据表示为文本,数字或两者的任意组合。

那么回顾一下,序列化如何在字节/位级别上工作,何时应该使用它,何时不应该使用它,以及序列化的真正好处除了在Java中是标准配置之外,还有什么真正的好处?


答案 1

我个人会尽量避免Java的“内置”序列化:

  • 它不能移植到其他平台
  • 它不是非常高效
  • 它很脆弱 - 让它处理一个类的多个版本有点棘手。即使更改编译器也会破坏序列化,除非您小心。

有关实际字节含义的详细信息,请参阅 Java 对象序列化规范

有多种替代方法,例如:

(免责声明:我为Google工作,并且我正在将协议缓冲区移植到C#作为我的20%项目,所以很明显我认为这是一个很好的技术:)

由于显而易见的原因,跨平台格式几乎总是比特定于平台的格式更具限制性 - 例如,协议缓冲区具有相当有限的本机类型集 - 但互操作性可能非常有用。您还需要考虑版本控制的影响,具有向后和向前兼容性等。文本格式通常是可手动编辑的,但在空间和时间上往往效率较低。

基本上,您需要仔细查看您的要求。


答案 2

序列化的主要优点是它非常易于使用,相对较快,并保留了实际的Java对象网格。

但是你必须意识到,它并不是真正用于存储数据,而主要是作为不同JVM实例使用RMI协议通过网络进行通信的一种方式。