匿名函数可序列化的机制是什么?

时间:2018-01-03 16:19:27

标签: scala serialization

我已经阅读了关于这个一般主题的各种旧的StackOverflow讨论,但至少在我看来还有一部分难以出现。

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

或者只是魔术?

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

1 个答案:

答案 0 :(得分:1)

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

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

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

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

没有(额外的)字节代码的编译/反编译是必要的,因为classLoader具有所有必要的内容。我在java.io而不是在反射包中找到了ObjectStreamClass,我感到有些惊讶,但我认为它存在一个参数,因为与 ObjectInputStream 紧密耦合和 ObjectOutputStream

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

还有一点要注意的是,在Scala 2.12中,匿名函数现在以不同的方式实现:作为Java8 lambdas。这已经以相当严重的方式打破了上述机制。如此严重,Spark目前在支持Scala 2.12时遇到了麻烦。劫持似乎是这个问题:SPARK-14540