Почему объекты case сериализуемы, а классы case нет?

Я играю с этим примером 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

и все работает, как ожидалось. К сожалению, если я определяю события как классы case вместо объектов case, как в:

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

, мой пример перестанет работать. Более подробно кажется, что, хотя объекты case являются сериализуемыми, классы case - нет. Действительно, когда я пытаюсь запустить свой пример с этой последней модификацией, я получаю следующее исключение:

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 - ' т? Есть ли способ заставить мой пример работать и с классами case?

Edit: как было предложено Виктором и подтверждено Аароном, я отправляю сопутствующий объект как сообщение вместо класса. Более того, при проверке скомпилированного кода с помощью 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

Теперь вопрос: как я могу указать, что я хочу использовать класс вместо сопутствующего объекта ? Я также добавил пустую пару скобок, когда отправляю сообщение, как предложил Аарон, например:

pong ! Ping()

, но ничего не изменилось. В конце концов, я также добавил фальшивый параметр в класс случая

case class Ping(i: Int) extends Event

, отправив сообщение как:

pong ! Ping(0)

, но по-прежнему не ощущая никакой разницы. Есть предложения?

11
задан Mario Fusco 2 November 2010 в 20:32
поделиться