Scala 中的不变性和自定义反序列化

Immutability and custom deserialization in Scala

函数式程序员告诉我们不变性高于一切,因此将所有字段声明为 vals 而不是 vars。就我个人而言,我还喜欢通过编译器强制字段保持不变。但是,您如何在自定义反序列化期间初始化这些字段?

我查过了,系统反序列化可以更新常量

case class S(value: String) extends Serializable {

    private def writeObject(out: ObjectOutputStream)  = out.defaultWriteObject()

    private def readObject(in: ObjectInputStream) {
        println("restoring " + this) // restoring S(null)
        in.defaultReadObject()
        println("restored to " + this) // restored S(string 1)
    }


}

而我手动不能这样做

case class I(value: Int) extends Serializable {

    private def readObject(in: ObjectInputStream) {
        value = in.readInt() // compilation error "reassignment to val"
    }

}

一个字:反思。特别是 Java 反思。 Java反射对Scala的语义一无所知,所以它会很乐意让你做Scala中禁止的事情。事实上,Java的反射系统是不安全的,它甚至会让你做Java!

中禁止的事情

如果您查看 the source code for Serializable,您会发现它实际上是空的。并简单地依赖于 Java 的序列化。

(事实上,在某些情况下,您甚至不需要反射来破坏 Scala 的语义。Java 会很乐意让您扩展 sealed trait 或 class,因为Java 不知道 sealed。)