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

时间:2018-09-14 19:06:44

标签: java scala kryo

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

如果该对象的具体类别未知,并且该对象可能为null

  

kryo.writeClassAndObject(输出,对象);

     

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:   无法创建类(缺少no-arg构造函数):   com.romix.scala.serialization.kryo.ScalaProductSerializer

我只是不明白为什么。

之前使用相同的代码,而不是使用我的类RawData,而是使用Map,它与writeObject和ReadObject一样具有吸引力。因此,我感到困惑。

有人可以帮助理解吗?

1 个答案:

答案 0 :(得分:1)

区别如下:

  • 在使用以下序列化程序时,您使用writeClassAndObjectreadClassAndObject
    • 序列化基本类型:接口,具有子类的类,或者-在Scala的情况下-Product之类的特征,
    • 需要反序列化对象的类型(即Class对象)来构造此对象(没有此类型,它不知道什么构建),
    • 示例:ScalaProductSerializer
  • 在使用以下序列化程序时,您使用writeObjectreadObject

总结一下您的具体情况:

  • 反序列化RawData时:
    • ScalaProductSerializer 需要找出创建实例的Product的确切类型,
    • 因此它使用typ: Class[Product]参数来实现,
    • 因此,只有readClassAndObject有效。
  • 反序列化Scala不变地图(以IMap导入的scala.collection.immutable.Map时):
    • ScalaImmutableAbstractMapSerializer 不需要找出确切的类型-它使用IMap.empty创建实例,
    • 因此,它不使用typ: Class[IMap[_, _]]参数,
    • 因此,readObjectreadClassAndObject都可以工作。