我正在使用这个示例http://scala.sygneca.com/code/remoteactors来了解远程参与者如何在 Scala (2.8.0) 中工作。特别是,我稍微修改了参与者发送的消息的定义方式,如下所示:
sealed trait Event extends Serializable
case object Ping extends Event
case object Pong extends Event
case object Quit extends Event
一切都按预期工作。不幸的是,如果我将事件定义为案例类而不是案例对象,如下所示:
sealed trait Event extends Serializable
case class Ping extends Event
case class Pong extends Event
case class Quit extends Event
我的例子停止工作。更详细地说,虽然案例对象是可序列化的,但案例类不是。实际上,当我尝试使用最后一次修改运行我的示例时,我得到以下异常:
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)
案例对象可以序列化而案例类不能序列化是否有原因?有没有办法让我的示例与案例类一起使用?
编辑:正如 Victor 所建议并由 Aaron 确认的那样,我将伴随对象作为消息而不是类发送。此外,使用 javap 检查编译的代码很明显,虽然该类是可序列化的:
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 的建议发送消息时,我还添加了一对空括号,如下所示:
pong ! Ping()
但没有任何改变。最后我还在案例类中添加了一个假参数
case class Ping(i: Int) extends Event
将消息发送为:
pong ! Ping(0)
但仍然没有任何区别。有什么建议吗?