【问题标题】:@transient lazy val field serialization@transient 惰性 val 字段序列化
【发布时间】:2011-06-13 22:56:55
【问题描述】:

我在 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 lazy-evaluation transient


    【解决方案1】:

    在 Scala 的 Trac 中有几张关于此的门票:

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

    【讨论】:

    • 非常感谢。我会尝试 2.9。
    • 只是一个更新,这在 Scala 2.10.4 中运行良好。但是,我注意到如果初始化程序依赖于一个别名参数,它仍然会被破坏。例如,将 ClassA.name 设置为 => String 它将不起作用。 (您还需要将其设为扩展 Serializable 的非 case 类,并将 name 设为 val。)
    猜你喜欢
    • 2016-04-18
    • 2018-03-22
    • 2015-03-09
    • 2021-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多