Подтвердить что ты не робот

Как использовать объект @serializable scala?

Я знаю, что вы можете пометить объект scala как @serializable, но я не понимаю, что делать с объектом впоследствии. Я просто рассматриваю его как объект Java Serializable?

Я хочу сериализовать объект в поток байтов. Может ли кто-нибудь показать мне код для преобразования объекта сериализации в массив байтов или строку?

(googles не помогли с этим вопросом)

FOLLOWUP: Спасибо. Теперь я понимаю, что я могу использовать его как объект Java Serializable. Иногда явный ответ убегает от меня.

4b9b3361

Ответ 1

Чтобы ответить на ваш первый вопрос: да, вы можете рассматривать его как объект Java Serializable:


scala> @serializable object A
defined module A

scala> import java.io.ByteArrayOutputStream;
import java.io.ByteArrayOutputStream

scala> import java.io.ObjectOutputStream;
import java.io.ObjectOutputStream

scala> val baos = new ByteArrayOutputStream(1024)
baos: java.io.ByteArrayOutputStream = 

scala> val o = new ObjectOutputStream(baos)
o: java.io.ObjectOutputStream = [email protected]

scala> o.writeObject(A)

scala> baos.toByteArray
res4: Array[Byte] = Array(-84, -19, 0, 5, 115, 114, 0, 24, 108, 105, 110, 101, 49, 51, 36, 111, 98, 106, 101, 99, 116, 36, 36, 105, 119, 36, 36, 105, 119, 36, 65, 36, 110, -104, -28, -53, -123, -97, -118, -36, 2, 0, 0, 120, 112)

scala> object B
defined module B

scala> o.writeObject(B)
java.io.NotSerializableException: B$
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
    at .(:13)
    at .()
    at RequestResult$.(:9)
    at RequestResult$.()
    at RequestResult$scala_repl_result()
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$18.apply(Interpreter.scala:981)
    at scala.tools.nsc.Interpreter$Request$...

Если вы хотите сериализовать в какой-то строковый формат, возможно, эта библиотека может быть полезна, которая сериализует объекты scala в JSON.

Ответ 2

В общем, я бы не рекомендовал сериализацию объектов, однако это может быть способ отправить ваше "глобальное состояние" по сети.

Что касается того, как отправлять/получать данные, проверьте java.io.ObjectOutputStream и java.io.ObjectInputStream.

scala> trait Test { def x : Int }
defined trait Test

scala> @serializable object Foo { var x = 5 }
defined module Foo


scala> import java.io._                                                     
import java.io._

scala> def write() {
     | val output = new ObjectOutputStream(new FileOutputStream("test.obj"))
     | output.writeObject(Foo)
     | output.close()
     | }
write: ()Unit


scala> write()

scala> def read() = {
     | val input = new ObjectInputStream(new FileInputStream("test.obj"))
     | val obj = input.readObject()
     | input.close()
     | obj
     | }
read: ()java.lang.Object

scala> Foo.x = 7

scala> val r = read()
r: Test = [email protected]

scala> r.x
res39: Int = 7

Вы видите... объекты верхнего уровня не очень хорошо работают с сериализацией. Однако вложенный объект может быть сериализован. Например:

scala> @serializable
     | class SomeClass(var y : Int) {
     |   @serializable object X extends Test {  def x  = y }
     | }
defined class SomeClass


scala> def write(x : AnyRef) {
     | val output = new ObjectOutputStream(new FileOutputStream("test.obj"))
     | output.writeObject(x)
     | output.close()
     | }
write: (x : AnyRef)Unit

scala> def read[A] = {
     | val input = new ObjectInputStream(new FileInputStream("test.obj"))
     | val obj = input.readObject()
     | input.close()
     | obj.asInstanceOf[A]
     | }
read: [A]A

scala> write(x.X)

scala> val y = read[Test]
y: Test = [email protected]

scala> y.x
res51: Int = 10

scala> x.y = 20  

scala> x.X.x
res52: Int = 20

scala> y.x
res53: Int = 10

Надеюсь, что это поможет!