如何使用 @serializable scala 对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3442171/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:21:02  来源:igfitidea点击:

How do I use a @serializable scala object?

scalaserialization

提问by Fred Haslam

I know that you can mark a scala object as @serializable, but I don't understand what to do with the object afterwards. Do I simply treat it as a Java Serializable object?

我知道您可以将 Scala 对象标记为@serializable,但我不明白之后如何处理该对象。我是否只是将其视为 Java Serializable 对象?

I want to serialize the object into a stream of bytes. Can someone show me the code to transform a serialize object into either a byte array or a string?

我想将对象序列化为字节流。有人可以向我展示将序列化对象转换为字节数组或字符串的代码吗?

(the googles have not been helpful with this question)

(谷歌对这个问题没有帮助)

FOLLOWUP: Thanks. I now understand that I can use it like a Java Serializableobject. Sometimes the obvious answer escapes me.

跟进:谢谢。我现在明白我可以像使用 JavaSerializable对象一样使用它。有时,显而易见的答案让我望而却步。

回答by Arjan Blokzijl

To answer your first question: yes you can treat it as a Java Serializable object:

回答您的第一个问题:是的,您可以将其视为 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 = java.io.ObjectOutputStream@3d689405

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$$anonfun$apply.apply(Interpreter.scala:981)
    at scala.tools.nsc.Interpreter$Request$...

If you want to serialize to some string format, perhaps this librarymay be useful, which serializes scala objects into JSON.

如果您想序列化为某种字符串格式,也许这个库可能很有用,它将 scala 对象序列化为 JSON。

回答by jsuereth

In general, I wouldn't recommend serializing Objects, however it could be a way to send your "global state" across the net.

一般来说,我不建议序列化对象,但它可能是一种通过网络发送“全局状态”的方法。

As for how to send/receive data check out java.io.ObjectOutputStream and java.io.ObjectInputStream.

至于如何发送/接收数据,请查看 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 = Foo$@2855e552

scala> r.x
res39: Int = 7

You see... top level objects don't really work well with serialization. However a nested object could be serialized. For example:

你看......顶级对象在序列化中并不能很好地工作。然而,嵌套对象可以被序列化。例如:

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 = SomeClass$X$@58e39f23

scala> y.x
res51: Int = 10

scala> x.y = 20  

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

scala> y.x
res53: Int = 10

Hope that helps!

希望有帮助!