当前位置: 首页 > 面试题库 >

Java的序列化如何工作以及何时应使用它来代替某些其他持久性技术?

狄卓君
2023-03-14
问题内容

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

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

我这里的问题之一是,我对ArrayList进行了一个小测试,其中包含值“一个”,“两个”,“三个”。序列化后,字节数组占用了78个字节,对于这么少的信息量(19
+ 3 + 3 + 4字节)来说,这似乎是一个很大的数目。当然会有一定的开销,但这引出了我的第二个问题:

2:是否 可以将序列化视为持久存储对象的好方法?现在显然,如果我使用一些自制的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的标准配置)?


问题答案:

我个人将尝试避免Java的“内置”序列化:

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

有关实际字节的含义的详细信息,请参见Java Object Serialization
Specification

有多种选择,例如:

  • 正如您所展示的,XML和JSON(当然有各种XML风格)
  • YAML
  • Facebook的Thrift(RPC以及序列化)
  • Google协议缓冲区
  • 黑森州(网络服务以及序列化)
  • 阿帕奇(Apache Avro)
  • 您自己的自定义格式

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

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

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



 类似资料:
  • 将SQL插入/更新表达式嵌入到刷新中 此功能允许将数据库列的值设置为SQL表达式,而不是文字值。它对于原子更新、调用存储过程等特别有用。您所要做的就是为属性分配一个表达式:: class SomeClass(Base): __tablename__ = "some_table" # ... value = Column(Integer) someobject = se

  • 问题内容: 经常出现在Python模块中。即使阅读了Python的文档,我也不明白它的用途以及使用时间/方式。 有人可以举例说明吗? 关于我收到的基本用法的一些答案似乎是正确的。 但是,我需要了解有关工作原理的另一件事: 对我来说,最令人困惑的概念是当前的python版本如何包含未来版本的功能,以及如何使用当前版本的Python成功地编译使用未来版本的功能的程序。 我猜想当前版本包含了将来的潜在功

  • 问题内容: 我想以一种人类可读的方式将.NET对象序列化为JSON,但是我想对对象的属性还是数组的元素以自己的一行结束进行更多控制。 目前,我正在使用JSON.NET的方法进行序列化,但似乎只能为整个对象全局应用(单个行中的所有元素)或(单个行中的所有元素,没有任何空格)格式化规则。有没有一种方法可以默认使用全局缩进,但是对于某些类或属性(例如,使用属性或其他参数)将其关闭? 为了帮助您理解问题,

  • 我们有一个旧的企业系统,在persistece中定义了不同的持久性单元。在xml中,许多服务使用entityManager,并用@PersistenceContext(unitName=“some_of_they_unit_names”)等注释。 现在我们用Spring Boot减去较小的后端。因此,在很长一段时间里,jpa配置看起来是这样的: 在应用程序启动时,日志中有一行:“在some_per

  • 问题内容: 如果我有一个存储在会话中的类的实例,则需要使其可序列化。此类具有静态变量,是否在每个存储的实例中将其序列化? 静态变量是对在后台包含大量数据的缓存的引用。是否将所有这些数据序列化?如果是这样,则使该变量成为瞬态并在每次还原实例时重新获取缓存实例似乎是可取的。也许根本不将缓存实例存储在类中。 从序列化状态恢复类时,构造函数将执行吗?如果没有,我可以使用其他任何方法来恢复瞬态变量吗? 问题

  • 何时扩展RecyclerView.Adapter以及它是如何工作的? 我理解一段代码有困难。有人能解释一下这个方法什么时候扩展,它是用来做什么的吗?