Scala @瞬时延迟val字段序列化

Scala @瞬时延迟val字段序列化,scala,lazy-evaluation,transient,Scala,Lazy Evaluation,Transient,我在Scala上有个问题。我用@transient lazy val字段序列化类的实例。然后我对它进行反序列化,字段被赋值为null。我希望在反序列化之后进行延迟计算。我该怎么办 下面是一个示例代码 object Test { def main(args: Array[String]){ //---------------- // ClassA - with @transient //---------------- val objA1 = ClassA

我在Scala上有个问题。我用
@transient lazy val
字段序列化类的实例。然后我对它进行反序列化,字段被赋值为
null
。我希望在反序列化之后进行延迟计算。我该怎么办

下面是一个示例代码

object Test {

  def main(args: Array[String]){

    //----------------
    // ClassA - with @transient
    //----------------

    val objA1 = ClassA("world");

    println(objA1);
    // This works as expected as follows:
    //   "Good morning."
    //   "Hello, world"

    saveObject("testA.dat", objA1);

    val objA2 = loadObject("testA.dat").asInstanceOf[ClassA];

    println(objA2);
    // I expect this will work as follows:
    //   "Good morning."
    //   "Hello, world"
    // but actually it works as follows:
    //   "null"



    //----------------
    // ClassB - without @transient
    // this works as expected
    //----------------

    val objB1 = ClassB("world");

    println(objB1);
    // This works as expected as follows:
    //   "Good morning."
    //   "Hello, world"

    saveObject("testB.dat", objB1);

    val objB2 = loadObject("testB.dat").asInstanceOf[ClassB];

    println(objB2);
    // This works as expected as follows:
    //   "Hello, world"

  }

  case class ClassA(name: String){

    @transient private lazy val msg = {
      println("Good morning.");
      "Hello, " + name;
    }

    override def toString = msg;

  }

  case class ClassB(name: String){

    private lazy val msg = {
      println("Good morning.");
      "Hello, " + name;
    }

    override def toString = msg;

  }

  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;

  def saveObject(fname: String, obj: AnyRef){
    val fop = new FileOutputStream(fname);
    val oop = new ObjectOutputStream(fop);
    try {
      oop.writeObject(obj);
    } finally {
      oop.close();
    }
  }

  def loadObject(fname: String): AnyRef = {
    val fip = new FileInputStream(fname);
    val oip = new ObjectInputStream(fip);
    try {
      oip.readObject();
    } finally {
      oip.close();
    }
  }

}

Scala的Trac上有几张票:


我建议您使用2.9的主干版本进行测试,因为它可能已经修复。

非常感谢。我将尝试2.9。这只是一个在Scala 2.10.4中运行良好的更新。但是,我注意到,如果初始值设定项依赖于by-name参数,它仍然会被破坏。例如,将ClassA.name设为
=>String
,它将不起作用。(您还需要将其设置为扩展Serializable的非case类,并将name设置为val。)