Kryo:readClassAndObject/ReadObject 和 WriteClassAndObject/WriteObject 之间的区别
Kryo: Difference between readClassAndObject/ReadObject and WriteClassAndObject/WriteObject
我试图从文档中理解以下声明:
如果对象的具体class未知且对象可能为空:
kryo.writeClassAndObject(output, object);
Object object = kryo.readClassAndObject(input);
如果具体 class 不确切知道怎么办。
我有以下代码:
case class RawData(modelName: String,
sourceType: String,
deNormalizedVal: String,
normalVal: Map[String, String])
object KryoSpike extends App {
val kryo = new Kryo()
kryo.setRegistrationRequired(false)
kryo.addDefaultSerializer(classOf[scala.collection.Map[_,_]], classOf[ScalaImmutableAbstractMapSerializer])
kryo.addDefaultSerializer(classOf[scala.collection.generic.MapFactory[scala.collection.Map]], classOf[ScalaImmutableAbstractMapSerializer])
kryo.addDefaultSerializer(classOf[RawData], classOf[ScalaProductSerializer])
//val testin = Map("id" -> "objID", "field1" -> "field1Value")
val testin = RawData("model1", "Json", "", Map("field1" -> "value1", "field2" -> "value2") )
val outStream = new ByteArrayOutputStream()
val output = new Output(outStream, 20480)
kryo.writeClassAndObject(output, testin)
output.close()
val input = new Input(new ByteArrayInputStream(outStream.toByteArray), 4096)
val testout = kryo.readClassAndObject(input)
input.close()
println(testout.toString)
}
当我使用 readClassAndObject 和 writeClassAndObject 时有效。但是,如果我使用 writeObject 和 readObject,则不会。
Exception in thread "main" com.esotericsoftware.kryo.KryoException:
Class cannot be created (missing no-arg constructor):
com.romix.scala.serialization.kryo.ScalaProductSerializer
我只是不明白为什么。
早些时候使用相同的代码,而不是使用我的 class RawData,我使用了一个 Map,它与 writeObject 和 ReadObject 一起工作就像一个魅力。因此我很困惑。
谁能帮忙看懂?
区别如下:
- 当您使用序列化程序时,您使用
writeClassAndObject
和 readClassAndObject
:
- 序列化一个 基本类型 :一个接口,一个具有子 class 的 class,或者 - 在 Scala 的情况下 - 像
Product
,
- 和需要反序列化对象的类型(即
Class
对象)来构造这个对象(没有这个类型就不知道构建什么),
- 示例:
ScalaProductSerializer
- 当您使用序列化程序时,您使用
writeObject
和 readObject
:
- 只序列化一种类型(即可以实例化的class;示例:
EnumSetSerializer
),
- 或 序列化不止一种类型,但可以从序列化数据中以某种方式推导出特定类型(示例:
ScalaImmutableAbstractMapSerializer
)
针对您的具体情况总结一下:
- 反序列化
RawData
时:
ScalaProductSerializer
需要找出Product
的确切类型来创建实例,
- 所以它使用
typ: Class[Product]
参数来完成,
- 因此,只有
readClassAndObject
有效。
- 反序列化 Scala 不可变映射时(
scala.collection.immutable.Map
导入为 IMap
):
ScalaImmutableAbstractMapSerializer
不需要找出确切的类型 - 它使用 IMap.empty
创建一个实例,
- 因此,它没有使用
typ: Class[IMap[_, _]]
参数,
- 因此,
readObject
和 readClassAndObject
都有效。
我试图从文档中理解以下声明:
如果对象的具体class未知且对象可能为空:
kryo.writeClassAndObject(output, object);
Object object = kryo.readClassAndObject(input);
如果具体 class 不确切知道怎么办。
我有以下代码:
case class RawData(modelName: String,
sourceType: String,
deNormalizedVal: String,
normalVal: Map[String, String])
object KryoSpike extends App {
val kryo = new Kryo()
kryo.setRegistrationRequired(false)
kryo.addDefaultSerializer(classOf[scala.collection.Map[_,_]], classOf[ScalaImmutableAbstractMapSerializer])
kryo.addDefaultSerializer(classOf[scala.collection.generic.MapFactory[scala.collection.Map]], classOf[ScalaImmutableAbstractMapSerializer])
kryo.addDefaultSerializer(classOf[RawData], classOf[ScalaProductSerializer])
//val testin = Map("id" -> "objID", "field1" -> "field1Value")
val testin = RawData("model1", "Json", "", Map("field1" -> "value1", "field2" -> "value2") )
val outStream = new ByteArrayOutputStream()
val output = new Output(outStream, 20480)
kryo.writeClassAndObject(output, testin)
output.close()
val input = new Input(new ByteArrayInputStream(outStream.toByteArray), 4096)
val testout = kryo.readClassAndObject(input)
input.close()
println(testout.toString)
}
当我使用 readClassAndObject 和 writeClassAndObject 时有效。但是,如果我使用 writeObject 和 readObject,则不会。
Exception in thread "main" com.esotericsoftware.kryo.KryoException: Class cannot be created (missing no-arg constructor): com.romix.scala.serialization.kryo.ScalaProductSerializer
我只是不明白为什么。
早些时候使用相同的代码,而不是使用我的 class RawData,我使用了一个 Map,它与 writeObject 和 ReadObject 一起工作就像一个魅力。因此我很困惑。
谁能帮忙看懂?
区别如下:
- 当您使用序列化程序时,您使用
writeClassAndObject
和readClassAndObject
:- 序列化一个 基本类型 :一个接口,一个具有子 class 的 class,或者 - 在 Scala 的情况下 - 像
Product
, - 和需要反序列化对象的类型(即
Class
对象)来构造这个对象(没有这个类型就不知道构建什么), - 示例:
ScalaProductSerializer
- 序列化一个 基本类型 :一个接口,一个具有子 class 的 class,或者 - 在 Scala 的情况下 - 像
- 当您使用序列化程序时,您使用
writeObject
和readObject
:- 只序列化一种类型(即可以实例化的class;示例:
EnumSetSerializer
), - 或 序列化不止一种类型,但可以从序列化数据中以某种方式推导出特定类型(示例:
ScalaImmutableAbstractMapSerializer
)
- 只序列化一种类型(即可以实例化的class;示例:
针对您的具体情况总结一下:
- 反序列化
RawData
时:ScalaProductSerializer
需要找出Product
的确切类型来创建实例,- 所以它使用
typ: Class[Product]
参数来完成, - 因此,只有
readClassAndObject
有效。
- 反序列化 Scala 不可变映射时(
scala.collection.immutable.Map
导入为IMap
):ScalaImmutableAbstractMapSerializer
不需要找出确切的类型 - 它使用IMap.empty
创建一个实例,- 因此,它没有使用
typ: Class[IMap[_, _]]
参数, - 因此,
readObject
和readClassAndObject
都有效。