Kryo:readClassAndObject / ReadObject和WriteClassAndObject / WriteObject之间的区别

问题描述 投票:1回答:1

我试图从文档中理解以下声明:

如果对象的具体类未知且对象可能为null:

kryo.writeClassAndObject(output,object);

Object object = kryo.readClassAndObject(input);

如果确切地知道具体类别怎么办?

我有以下代码:

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,它就不会。

线程“main”中的异常com.esotericsoftware.kryo.KryoException:无法创建类(缺少无参数构造函数):com.romix.scala.serialization.kryo.ScalaProductSerializer

我只是不明白为什么。

早些时候使用相同的代码,而不是使用我的类RawData,我使用了Map,它就像一个带有writeObject和ReadObject的魅力。因此我很困惑。

有人可以帮忙理解吗?

java scala kryo
1个回答
1
投票

区别如下:

  • 当您使用以下序列化程序时,使用writeClassAndObjectreadClassAndObject: 序列化基类型:接口,具有子类的类,或者 - 在Scala的情况下 - 像Product这样的特征, 并且需要反序列化对象的类型(即Class对象)来构造这个对象(没有这种类型,它不知道要构造什么), 例如:ScalaProductSerializer
  • 当您使用以下序列化程序时,使用writeObjectreadObject: 序列化一种类型(即可以实例化的类;例如:EnumSetSerializer), 或序列化多种类型,但特定类型可以从序列化数据中推导出来(例如:ScalaImmutableAbstractMapSerializer

为您的具体情况总结一下:

  • 当你反序列化你的RawData时: ScalaProductSerializer需要找出Product的确切类型来创建一个实例, 所以它使用typ: Class[Product]参数来做到这一点, 因此,只有readClassAndObject工作。
  • 当您反序列化Scala不可变映射(scala.collection.immutable.Map导入为IMap)时: ScalaImmutableAbstractMapSerializer不需要找出确切的类型 - 它使用IMap.empty来创建一个实例, 因此,它不使用typ: Class[IMap[_, _]]参数, 结果,readObjectreadClassAndObject工作。
© www.soinside.com 2019 - 2024. All rights reserved.