我是scala编程语言的新手,我目前需要执行以下操作。我有一个像下面这样的符号对象:
object MyObject extends Serializable {
val map: HashMap[String, Int] = null
val x: int = -1;
val foo: String = ""
}
现在我想避免必须单独序列化该对象的每个字段,因此我正在考虑将整个对象写入文件,然后,在下一次执行程序时,读取文件并初始化单例对象从那里。有没有办法做到这一点?
基本上我想要的是当序列化文件不存在时,那些要初始化为新结构的变量,当它存在时,要从文件中的那些字段初始化的字段。但我想避免手动序列化/反序列化每个字段......
更新:
我必须使用这里提供的自定义反序列化器:https://issues.scala-lang.org/browse/SI-2403,因为我在HashMap中使用的自定义类有问题。
UPDATE2:
以下是我用于序列化的代码:
val store = new ObjectOutputStream(new FileOutputStream(new File("foo")))
store.writeObject(MyData)
store.close
反序列化的代码(在不同的文件中):
@transient private lazy val loadedData: MyTrait = {
if(new File("foo").exists()) {
val in = new ObjectInputStream(new FileInputStream("foo")) {
override def resolveClass(desc: java.io.ObjectStreamClass): Class[_] = {
try { Class.forName(desc.getName, false, getClass.getClassLoader) }
catch { case ex: ClassNotFoundException => super.resolveClass(desc) }
}
}
val obj = in.readObject().asInstanceOf[MyTrait]
in.close
obj
}
else null
}
谢谢,
答案 0 :(得分:1)
不需要仅使用不可变字段序列化对象(因为编译器会为您执行此操作...)我将假设该对象提供了默认值。这是一种方法:
首先编写一个包含所有必填字段的特征:
trait MyTrait {
def map: HashMap[String, Int]
def x: Int
def foo: String
}
然后用默认值编写一个对象:
object MyDefaults extends MyTrait {
val map = Map()
val x = -1
val foo =
}
最后编写一个实现反序列化数据(如果存在):
object MyData extends MyTrait {
private lazy val loadedData: Option[MyTrait] = {
if( /* filename exists */ ) Some( /*unserialize filename as MyTrait*/)
else None
}
lazy val map = loadedData.getOrElse( MyDefault ).map
lazy val x = loadedData.getOrElse( MyDefault ).x
lazy val foo = loadedData.getOrElse( MyDefault ).foo
}