当我有一个在val上有方法的case类时,究竟将序列化什么?
case class User(id: Int, name: String, age: Int) {
val someNumber = age * 10
def someMethod(a: Int) = ....
}
所以从上面我会想象构造函数参数和val someNumber会被序列化,而方法不会。
所以基本上方法的状态被序列化了。
scala和java序列化之间有什么重大差异吗?
答案 0 :(得分:4)
case class
序列化是我们对标准Java序列化的期望。
案例类扩展scala.Serializable
,后者又扩展Any with java.io.Serializable
(请参阅scala.Serializable),因此使用通常的扩展java.io.Serializable
Java方法对案例类进行“标记”序列化
请注意,我们应该谈论对象序列化,而不是类序列化。序列化的是对象实例的状态,它由声明或继承的所有成员的值组成。在无体case class
的情况下,如
case class User (id:Long, name:String)
所有已声明的成员都将被序列化(例如id
,name
)。
如果case类声明了内部成员变量,那么它们也将包含在序列化形式中。
case class User (id:Long, name:String) {
val foo = name.hashCode * id
}
serializad表单将包含(id
,name
,foo
)。
我们可以使用@transient
注释标记成员,以避免它们被序列化。
case class User (id:Long, name:String) {
val foo = name.hashCode * id
@transient bar = "Private Bar."
}
serializad表单将包含(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)
所以,给定:
val beerPurchase = Purchase(now, onlineUser, leffe)
序列化beerPurchase
还会涉及onlineUser
和leffe
个对象的序列化。
请注意,可序列化类的每个成员也必须可序列化或标记为@transient
。否则,尝试序列化此类将导致运行时java.io.NotSerializableException
简而言之:没有惊喜。案例类序列化是您对标准java / jvm序列化的期望。
答案 1 :(得分:0)
让我们创建一个对象并将其序列化,以便您可以轻松查看正在序列化的内容:
case class City(name: String, funActivity: String, latitude: Double)
val bengaluru = City("Bengaluru", "South Indian food", 12.97)
implicit val cityRW = upickle.default.macroRW[City]
upickle.default.write(bengaluru) // "{\"name\":\"Bengaluru\",\"funActivity\":\"South Indian food\",\"latitude\":12.97}"
封装在对象中的值正在被序列化。
您可以编写序列化程序来将数据保存在对象中。你不能序列化任何 JVM 的东西/Scala 的东西。序列化意味着将对象转换为字符串/二进制。字节数组无法存储方法之类的 JVM 内容。有关序列化 Scala 对象的详细信息,请参阅 this post。