简体   繁体   中英

Scala serialization/deserialization of singleton object

I am quite new to the scala programming language, and I currently need to do the following. I have a signleton object like the following:

object MyObject extends Serializable {
    val map: HashMap[String, Int] = null
    val x: int = -1;
    val foo: String = ""
}

Now i want to avoid to have to serialize each field of this object separately, thus I was considering writing the whole object to a file, and then, in the next execution of the program, read the file and initialize the singleton object from there. Is there any way to do this?

Basically what I want is when the serialization file doesn't exist, those variables to be initialized to new structures, while when it exists, the fields to be initialized from the ones on the file. But I want to avoid having to serialize/deserialize every field manually...

UPDATE:

I had to use a custom deserializer as presented here: https://issues.scala-lang.org/browse/SI-2403 , since i had issues with a custom class I use inside the HashMap as values.

UPDATE2:

Here is the code I use to serialize:

val store = new ObjectOutputStream(new FileOutputStream(new File("foo"))) 
store.writeObject(MyData) 
store.close

And the code to deserialize (in a different file):

@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
}

Thanks,

No needs to serialize an object with only immutable fields (because the compiler will do it for you...) I will assume that the object provides default values. Here is a way to do this:

Start by writing an trait with all the required fields:

trait MyTrait {
  def map: HashMap[String, Int]
  def x: Int
  def foo: String
}

Then write an object with the defaults:

object MyDefaults extends MyTrait {
  val map = Map()
  val x = -1
  val foo = 
}

Finally write an implementation unserializing data if it exists:

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM