1

我对 scala 编程语言很陌生,我目前需要做以下事情。我有一个 signleton 对象,如下所示:

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 中作为值使用的自定义类存在问题。

更新2:

这是我用来序列化的代码:

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
}

谢谢,

4

1 回答 1

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

}
于 2012-12-05T10:11:17.693 回答