简体   繁体   中英

Kryo: Difference between readClassAndObject/ReadObject and WriteClassAndObject/WriteObject

I am trying to understand the following statement from the documentation:

If the concrete class of the object is not known and the object couldbe null :

kryo.writeClassAndObject(output, object);

Object object = kryo.readClassAndObject(input);

What does if the concrete class is not known exactly.

I am having the following code:

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)

}

When I use readClassAndObject and writeClassAndObject is works. However if I use writeObject and readObject it does not.

Exception in thread "main" com.esotericsoftware.kryo.KryoException: Class cannot be created (missing no-arg constructor): com.romix.scala.serialization.kryo.ScalaProductSerializer

I just don't understand why.

earlier using the same code, Instead of using my class RawData, I used a Map and it worked like a charm with writeObject and ReadObject. Hence i am confused.

Can someone help understand it ?

The difference is as follows:

  • you use writeClassAndObject and readClassAndObject when you're using a serializer that:
    • serializes a base type : an interface, a class that has subclasses, or - in case of Scala - a trait like Product ,
    • and needs the type (ie the Class object) of the deserialized object to construct this object (without this type, it doesn't know what to construct),
    • example: ScalaProductSerializer
  • you use writeObject and readObject when you're using a serializer that:

To sum this up for your specific case:

  • when you deserialize your RawData :
    • ScalaProductSerializer needs to find out the exact type of Product to create an instance,
    • so it uses the typ: Class[Product] parameter to do it,
    • as a result, only readClassAndObject works.
  • when you deserialze a Scala immutable map ( scala.collection.immutable.Map imported as IMap ):
    • ScalaImmutableAbstractMapSerializer doesn't need to find out the exact type - it uses IMap.empty to create an instance,
    • as a result, it doesn't use the typ: Class[IMap[_, _]] parameter,
    • as a result, both readObject and readClassAndObject work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM