我试图理解文档中的以下陈述:
如果对象的具体类未知并且该对象可能为空:
kryo.writeClassAndObject(output, object);
Object object = kryo.readClassAndObject(input);
如果不确切知 Prop 体类会怎样。
我有以下代码:
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
我只是不明白为什么。
之前使用相同的代码,我没有使用我的类 RawData,而是使用了 Map,它与 writeObject 和 ReadObject 一起工作就像一个魅力。因此我很困惑。
谁能帮忙理解一下吗?
最佳答案
区别如下:
- 当您使用以下序列化器时,您可以使用
writeClassAndObject
和readClassAndObject
:- 序列化一个基类型:一个接口(interface)、一个具有子类的类,或者 - 对于 Scala - 像
Product
这样的特征, - 和需要反序列化对象的类型(即
Class
对象)来构造这个对象(没有这个类型,它不知道什么 构建), - 示例:
ScalaProductSerializer
- 序列化一个基类型:一个接口(interface)、一个具有子类的类,或者 - 对于 Scala - 像
- 当您使用以下序列化器时,您可以使用
writeObject
和readObject
:- 仅序列化一种类型(即可以实例化的类;例如:
EnumSetSerializer
), - 或序列化多个类型,但可以通过序列化数据以某种方式推断出特定类型(例如:
ScalaImmutableAbstractMapSerializer
)
- 仅序列化一种类型(即可以实例化的类;例如:
根据您的具体情况总结一下:
- 当您反序列化
RawData
时:-
ScalaProductSerializer
需要找出Product
的确切类型来创建实例, - 因此它使用
typ: Class[Product]
参数来执行此操作, - 因此,只有
readClassAndObject
有效。
-
- 当您反序列化 Scala 不可变映射(
scala.collection.immutable.Map
作为IMap
导入)时:-
ScalaImmutableAbstractMapSerializer
不需要找出确切的类型 - 它使用IMap.empty
来创建一个实例, - 因此,它不使用
typ: Class[IMap[_, _]]
参数, - 因此,
readObject
和readClassAndObject
都可以工作。
-
关于java - Kryo:readClassAndObject/ReadObject 和 WriteClassAndObject/WriteObject 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52337925/