为什么 case 对象可序列化而 case 类不可序列化? [英] Why are case objects serializable and case classes not?

查看:64
本文介绍了为什么 case 对象可序列化而 case 类不可序列化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用这个示例 http://scala.sygneca.com/code/remoteactors 了解远程 actor 在 Scala (2.8.0) 中的工作方式.特别是,我稍微修改了参与者发送的消息的定义方式,如下所示:

I am playing with this example http://scala.sygneca.com/code/remoteactors to learn how remote actors work in Scala (2.8.0). In particular I slightly modified how the messages send by the actors are defined as it follows:

sealed trait Event extends Serializable
case object Ping extends Event
case object Pong extends Event
case object Quit extends Event

一切都按预期进行.不幸的是,如果我将事件定义为案例类而不是案例对象,如下所示:

and everything works as expected. Unfortunately if I define the events as case classes instead of case objects as in:

sealed trait Event extends Serializable
case class Ping extends Event
case class Pong extends Event
case class Quit extends Event

我的示例停止工作.更详细地说,虽然 case 对象是可序列化的,但 case 类不是.事实上,当我尝试使用最后一次修改运行我的示例时,我得到以下异常:

my example stop working. In more detail it seems that while case objects are serializable, case classes aren't. Indeed when I try to run my example with this last modification I get the following exception:

scala.actors.remote.DelegateActor@148cc8c: caught java.io.NotSerializableException: scalachat.remote.Ping$
java.io.NotSerializableException: scalachat.remote.Ping$
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
    at scala.actors.remote.JavaSerializer.serialize(JavaSerializer.scala:46)
    at scala.actors.remote.NetKernel.namedSend(NetKernel.scala:38)
    at scala.actors.remote.NetKernel.forward(NetKernel.scala:71)
    at scala.actors.remote.DelegateActor$$anonfun$act$1$$anonfun$apply$1.apply(Proxy.scala:182)
    at scala.actors.remote.DelegateActor$$anonfun$act$1$$anonfun$apply$1.apply(Proxy.scala:123)
    at scala.actors.ReactorTask.run(ReactorTask.scala:34)
    at scala.actors.ReactorTask.compute(ReactorTask.scala:66)
    at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
    at scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)

case 对象可以序列化而 case 类不能序列化的原因是什么?有没有办法让我的示例与案例类一起工作?

Is there a reason why case objects can be made serializable and case classes can't? Is there a way to make my example working with case classes either?

按照 Victor 的建议并由 Aaron 确认,我将伴随对象作为消息而不是类发送.此外,使用 javap 检查编译后的代码似乎很明显,虽然该类是可序列化的:

as suggested by Victor and confirmed by Aaron I am sending the companion object as message instead of the class. Moreover inspecting the compiled code with javap it appears evident that while the class is serializable:

public class scalachat.remote.Ping extends java.lang.Object implements scalachat.remote.Event,java.io.Serializable,scala.ScalaObject,scala.Product

伴随对象不是:

public final class scalachat.remote.Ping$ extends scala.runtime.AbstractFunction0 implements scala.ScalaObject

现在的问题是:如何指定我要使用类而不是伴随对象?当我按照 Aaron 的建议发送消息时,我还添加了一对空括号,例如:

Now the question is: how can I specify that I want to use the class instead of the companion object? I also added an empty couple of parenthesis when I send the message as suggested by Aaron like in:

pong ! Ping()

但没有任何改变.最后我还给case类加了一个假参数

but nothing is changed. In the end I also added a fake parameter to the case class

case class Ping(i: Int) extends Event

发送消息为:

pong ! Ping(0)

但仍然没有任何区别.有什么建议吗?

but without experiencing any difference still. Any suggestion?

推荐答案

@serializable case class Foo

我也很惊讶 case 对象默认是可序列化的.

I was also surprised that case objects were serializable per default.

正确阅读异常后,我怀疑:

After reading the exception properly I suspect that:

您正在尝试通过网络发送案例类的生成伴随对象,而不是案例类的实例.

You're trying to send the generated companion object of the case class over the wire, instead of an instance of the case class.

这篇关于为什么 case 对象可序列化而 case 类不可序列化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆