【问题标题】:What is the mechanism by which anonymous functions are serializable?匿名函数可序列化的机制是什么?
【发布时间】:2018-01-03 16:19:26
【问题描述】:

我已经阅读了关于这个一般性主题的各种旧 StackOverflow 讨论,但至少在我看来,这个谜题的一部分仍然缺失。

很简单:匿名函数序列化的实际机制是什么?而且,我们在哪里可以找到它的源代码?

或者这一切只是魔法?

其他相关的 SO 文章(其中第三篇本身指向 StockOverflow 之外的一些有用文章):

【问题讨论】:

    标签: scala serialization


    【解决方案1】:

    我将用什么来回答我自己的问题,我相信这是正确的答案。我这样做的原因是,在我看来,序列化的这一方面从未被解释过,而且它似乎只是靠魔法起作用。作为我正在做的研究的一部分,我基本上确认了答案(令我满意),以确保我的上述问题确实是合适的。

    但我提供自己的答案的主要原因是我邀请知识渊博的用户同意它、纠正它、扩展它或破坏它。来了……

    这一切都是魔法。不,我只是在开玩笑。但本质上,一旦 Scala 采取了将匿名函数表示为类的步骤,该机制完全由 Java 提供。此外,我们程序员需要确保匿名函数尽可能是纯代码:不引用任何可能无法序列化的对象。秘诀可以在 Java 类中找到:ObjectStreamClass。依次由 Java 序列化类调用:ObjectInputStreamObjectOutputStream

    基本上,序列化字节包含类的完整路径名、它的serialVersionUID,以及任何其他必要的相关信息。反序列化时,系统将简单地查找适当类路径中的类并返回对它的引用。这显然假设反序列化系统在其类路径中具有该类。其机制有点超出我的研究范围,但很明显,在像 Spark 这样的系统中,它应该很容易安排。

    不需要(额外的)字节码编译/反编译,因为类加载器拥有一切必要的东西。在 java.io 中而不是在反射包中找到 ObjectStreamClass 让我有点惊讶,但我想有一个论点,因为它与 ObjectInputStreamObjectOutputStream。

    要记住的一点是,虽然我们考虑的是序列化/反序列化 objects,而不是 classes,但我们在这里处理的是一个对象输入

    还有一点需要注意的是,在 Scala 2.12 中,匿名函数现在以不同的方式实现:作为 Java8 lambda。这以相当严重的方式破坏了上述机制。如此严重,以至于 Spark 目前无法支持 Scala 2.12。滞留似乎是这个问题:SPARK-14540

    【讨论】:

    • 这是正确的,是的。我不会将其描述为“魔术”,但这只是一个 POV :-)。 Scala 在编译时为它在代码中遇到的每个函数类型生成一个类。在运行时,它会为您创建的每个函数对象生成该类的实例,其中包含所有必要的运行时数据作为字段。这些对象可以通过 Java 的标准机制进行序列化和反序列化。
    • 谢谢@Rich,这是一个很有帮助的阐述。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多