与 java 相比,case 类的序列化如何工作?

coo*_*eze 4 serialization scala

当我有一个在 vals 上有方法的 case 类时,究竟会序列化什么?

case class User(id: Int, name: String, age: Int) {
  val someNumber = age * 10

  def someMethod(a: Int) = ....

}
Run Code Online (Sandbox Code Playgroud)

因此,从上面我将映像构造函数参数,并且 val someNumber 将被序列化,而方法则不会。

所以基本上方法的状态被序列化。

scala 和 java 序列化之间有什么大的区别吗?

maa*_*asg 6

case class Scala 中的序列化是我们对标准 Java 序列化所期望的。

case 类扩展scala.Serializable,而后者又扩展Any with java.io.Serializable(参见scala.Serializable),因此使用通常的 Java 扩展方法将 case 类“标记”为可序列化java.io.Serializable

请注意,我们应该谈论对象序列化,而不是类序列化。序列化的是对象实例的状态,它由所有成员的值组成,声明的或继承的。在没有 bodyless 的情况下case class,比如

case class User (id:Long, name:String)
Run Code Online (Sandbox Code Playgroud)

所有声明的成员都将被序列化(例如idname)。

如果 case 类声明了内部成员变量,则这些变量也将包含在序列化形式中。

case class User (id:Long, name:String) {
  val foo = name.hashCode * id
}
Run Code Online (Sandbox Code Playgroud)

序列化形式将包括 ( id, name,foo )。

我们可以用@transient注解标记成员以避免它们被序列化。

case class User (id:Long, name:String) {
  val foo = name.hashCode * id
  @transient bar = "Private Bar."
}
Run Code Online (Sandbox Code Playgroud)

序列化形式将包括 ( id, name,foo )。

请注意,Java 序列化始终涉及序列化由附加到被序列化对象的所有引用组成的对象图,因此任何被成员变量引用的对象也将被序列化。

就像在这种情况下:

case class User (id:Long, name:String)
case class Product (id:Long, name:String, price: Decimal)
case class Purchase (timestamp:Long, user:User, product:Product, name:String)
Run Code Online (Sandbox Code Playgroud)

所以,给定:

val beerPurchase = Purchase(now, onlineUser, leffe)
Run Code Online (Sandbox Code Playgroud)

序列化beerPurchase还将涉及onlineUserleffe对象。

请注意,可序列化类的每个成员也必须是可序列化的或被标记的@transient。否则,尝试序列化此类类将导致运行时java.io.NotSerializableException

简而言之:没有惊喜。case 类序列化是您对标准 java/jvm 序列化所期望的。